package com.wtwd.campus.wx.controller;


import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.common.RespEntity;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.service.*;
import com.wtwd.campus.sms.SendToChina;
import com.wtwd.campus.sms.SmsToInternational;
import com.wtwd.campus.thread.ForkJoinPushTask;
import com.wtwd.campus.utils.*;
import com.wtwd.campus.wx.entity.BindingStudentDto;
import com.wtwd.campus.wx.entity.UnbindWeChatUserDto;
import com.wtwd.campus.wx.service.WxUtilsService;
import com.wtwd.campus.wx.utils.PushModel;
import com.wtwd.campus.wx.utils.WXMessageBean;
import com.wtwd.campus.wx.utils.WxUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.jeewx.api.core.req.model.message.TemplateMessageSendResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


/**
 * @Author ldaoliang
 * @Date create in 13:37 2021/7/14
 * @Description
 */
@Api(tags = "微信")
@RestController
@RequestMapping("/wx/")
public class WxController {

    private static final Logger logger = LoggerFactory.getLogger(WxController.class);

    @Autowired
    private CommandSendUtils commandSendUtils;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DeviceWhiteListService deviceWhiteListService;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private DeviceClassPatternService deviceClassPatternService;
    @Autowired
    private WxService wxService;
    @Autowired
    private LocationService locationService;
    @Autowired
    private LogService logService;
    @Autowired
    private FenceInfoService fenceInfoService;
    @Autowired
    private DeviceSettingService deviceSettingService;
    @Autowired
    private InformationService informationService;
    @Autowired
    private NotificationService notificationService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private ClassService classService;
    @Autowired
    private DeviceAlarmService deviceAlarmService;
    @Autowired
    private AttendanceRulesService attendanceRulesService;

    @Autowired
    private WxCustomerService wxCustomerService;

    @Autowired
    private WXUserStudentPermissionService wxUserStudentPermissionService;

    @Autowired
    private WxUtilsService wxUtilsService;

    @Resource
    private LastLocationDataService lastLocationDataService;


    private String fixedOpenId = "obdQT6E9yFappDV4etV7quwxYCcA";
    private String fixedCode = "campusCardTest";
    private String defaultVerifyCode = "123456";
    private String defaultPhone = "13344445555";

    private static final Integer CW_CUSTOMER = 1;

    private static final Integer XB_CUSTOMER = 2;


    /**
     * 校验请求是否来自微信（平台）
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/subscribeByScan")
    public void wxValidate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("url:" + request.getRequestURI());
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        logger.info("signature, timestamp,nonce  -->" + signature + "," + timestamp + "," + nonce);
        if (!StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature)) {
            boolean b = WxVerifyRequestUtils.checkSignature(signature, timestamp, nonce);
            logger.info("验证是否微信：" + b);
            if (b) {
                response.getOutputStream().write(echostr.getBytes());
            }
        }
    }

    /**
     * 校验请求是否来自微信（平台）
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/subscribeXBByScan")
    public void subscribeXBByScan(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("url:" + request.getRequestURI());
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        logger.info("signature, timestamp,nonce  -->" + signature + "," + timestamp + "," + nonce);
        if (!StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature)) {
            boolean b = WxVerifyRequestUtils.checkSignatureXB(signature, timestamp, nonce);
            logger.info("验证是否微信：" + b);
            if (b) {
                response.getOutputStream().write(echostr.getBytes());
            }
        }
    }

    /**
     * 校验请求是否来自微信（瑞翼）
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/subscribeRyByScan")
    public void wxValidateRy(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("url:" + request.getRequestURI());
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        logger.info("signature, timestamp,nonce  -->" + signature + "," + timestamp + "," + nonce);
        if (!StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature)) {
            boolean b = WxVerifyRequestUtils.checkSignatureRy(signature, timestamp, nonce);
            logger.info("验证是否微信：" + b);
            if (b) {
                response.getOutputStream().write(echostr.getBytes());
            }
        }
    }

    /**
     * 校验请求是否来自创维
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/subscribeCWByScan")
    public void wxValidateCW(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("url:" + request.getRequestURI());
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        logger.info("signature, timestamp,nonce  -->" + signature + "," + timestamp + "," + nonce);
        if (!StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature) &&
                !StringUtils.isEmpty(signature)) {
            boolean b = WxVerifyRequestUtils.checkSignatureCW(signature, timestamp, nonce);
            logger.info("验证是否微信：" + b);
            if (b) {
                response.getOutputStream().write(echostr.getBytes());
            }
        }
    }

    /**
     * 处理用户从微信端发送的消息
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/subscribeByScan")
    public void dealMess(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("utf-8");
        PrintWriter out = null;
        //将接受的消息转成实体类
        Map<String, String> map = WxMessageUtils.xmlToMap(request);
        String toUserName = map.get("ToUserName");
        String fromUserName = map.get("FromUserName");
        String msgType = map.get("MsgType");
        String content = map.get("Content");
        String mess = "";
        logger.info("/dealMess: ToUserName={},FromUserName={},MsgType={},Content={}", toUserName, fromUserName, msgType, content);
       /* //根据不同消息进行回复，这里暂时不做处理
        //进行回复
        WxTextMessage reply=new WxTextMessage();
        reply.setFromUserName(toUserName);
        reply.setToUserName(fromUserName);
        reply.setMsgType("text");
        reply.setCreateTime(System.currentTimeMillis());
        reply.setContext(mess);
        String replyStr = WxMessageUtils.messToXml(reply);
        try {
            out=response.getWriter();
            out.print(replyStr);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(out != null){
                out.close();
            }
        }*/
    }


    /**
     * 处理用户从微信端发送的消息
     * 瑞翼：点击菜单显示 热线号码
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/subscribeRyByScan")
    public void dealMessRy(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            //将接受的消息转成实体类
            Map<String, String> map = WxMessageUtils.xmlToMap(request);
            String toUserName = map.get("ToUserName");
            String fromUserName = map.get("FromUserName");
            String msgType = map.get("MsgType");
            String eventKey = map.get("EventKey");
            String mess = "";
            logger.info("/dealMessRy: data={}", map.toString());
            if (msgType.equals("event")) {
                boolean flag = false;
                //根据不同消息进行回复
                if (eventKey.equals("aa")) {
                    logger.info("/设置回复内容");
                    mess = "售后服务热线：400-823-7018";
                    flag = true;
                }
                if (flag) {
                    //进行回复
                    WxTextMessage reply = new WxTextMessage();
                    reply.setFromUserName(toUserName);
                    reply.setToUserName(fromUserName);
                    reply.setMsgType("event");
                    reply.setCreateTime(System.currentTimeMillis());
                    reply.setContext(mess);
                    String replyStr = WxMessageUtils.messToXmlString(reply);
                    logger.info("回复xml：" + replyStr);
                    try {
                        outputStream.write(replyStr.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                //其他模块暂时不做处理
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 校验微信用户
     *
     * @param code 微信临时code（转openId用）
     * @return
     */
    @GetMapping(value = {"/verifyWxUser/{code}", "/verifyWxUser/{code}/{appKey}"})
    public RespEntity verifyWxUser(@PathVariable("code") String code, @PathVariable(value = "appKey", required = false) String appKey) {
        logger.info("verifyWxUser code ={},appkey={} ", code, appKey);
        if (StringUtils.isNotBlank(appKey)) {//只有客户携带appKey
            return dealWxCustomer(code, appKey);
        }
        String openId = "";
        String accessToken = null;
        String nickName = "";
        String headImg = "";
        if ("false".equals(code)) {
            logger.info("code为false，直接返回不处理");
            return new RespEntity(RespCode.SUCCESS);
        }
        //首先判断code是否能在缓存中找到
        if (redisService.hasKey(code)) {
            openId = redisService.getValue(code);
            //获取用户名和头像
            Map<String, Object> userInfo = redisService.getHash(openId);
            if (userInfo != null) {
                nickName = (String) userInfo.get("name");
                headImg = (String) userInfo.get("headImg");
            }
        } else {
            if (!code.equals(fixedCode)) {
                try {
                    Map<String, String> map = WxUtils.getAccessTokenAndOpenId(code);
                    openId = map.get("openId");
                    accessToken = map.get("accessToken");
                    //根据accessToken获取个人信息
                    Map<String, Object> userInfo = WxUtils.getUserInfo(accessToken, openId);
                    //保存openId和code对应关系，保存用户的头像和名称信息两天，与我们的免登录一致
                    redisService.setKey(code, openId, Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
                    redisService.setHash3(openId, userInfo, Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
                    nickName = (String) userInfo.get("name");
                    headImg = (String) userInfo.get("headImg");
                } catch (Exception e) {
                    return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
                }
            } else {
                openId = fixedOpenId;
            }
        }
        // 根据openId从wx_user表中查询数据
        logger.info("微信用户的openId：".concat(openId));
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        /* redisService.setKey(token, String.valueOf(addResult[1]), Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);*/
        redisService.setKey(token, String.valueOf(addResult[1]), 15, TimeUnit.DAYS);
        logger.info("verifyWxUser 存储微信用户token={),存储内容={}",token,String.valueOf(addResult[1]));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        jsonObject.put("nickName", nickName);
        jsonObject.put("headImage", headImg);
        logger.info("获取微信用户名称:".concat(nickName).concat("头像：").concat(headImg));
        jsonObject.put("type", Constants.PARENT_TYPE);
        //判断是否需要绑定，如果不需要，则给前端用户上次登录的类型
        if (addResult[0] == 0) {
            //获取用户手机号码
            WxUser wxUser = wxService.getWxUserByOpenId(openId);
            if (wxUser != null) {
                //根据手机号码获取用户类型
                String type = redisService.getValue(wxUser.getWxUserPhone().concat(Constants.WATER_USER_TYPE_PREFIX));
                if (type == null) {
                    logger.info("用户上次登录类型未存储，默认家长身份");
                    jsonObject.put("type", Constants.PARENT_TYPE);
                } else {
                    jsonObject.put("type", type);
                    logger.info("用户上次登录类型为：".concat(type));
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }

    /**
     * 根据不同的appKey做微信平台不同的处理
     */
    private RespEntity dealWxCustomer(String code, String appKey) {
        logger.info("dealWxCustomer code={},appkey={}", code, appKey);
        WxCustomer wxCustomer = wxCustomerService.getWxCustomerByAppKey(appKey);
        if (wxCustomer == null) {
            return new RespEntity(RespCode.APP_KEY_NOT_FOUND);
        }
        //进行过期时间判断
        if (System.currentTimeMillis() > wxCustomer.getExpireTime()) {
            return new RespEntity(RespCode.NO_RIGHT_OPERATION);
        }
        if (CW_CUSTOMER.equals(wxCustomer.getId())) {//如果是创维走创维处理
            return verifyWxUserCW(code);
        } else {//前面客户怕产生bug为同步未公用处理
            return verifyWxUserCustomer(wxCustomer.getId(), code, wxCustomer.getAppId(), wxCustomer.getAppSecret());
        }
    }


    /**
     * 校验微信用户(客户通用处理)
     */
    @GetMapping("/verifyWxUserCustomer")
    public RespEntity verifyWxUserCustomer(
            @RequestParam("customerId") Integer customerId,
            @RequestParam("code") String code,
            @RequestParam("appId") String appId,
            @RequestParam("appSecret") String appSecret
    ) {
        logger.info("verifyWxUserCustomer customerId={},code ={},appId={},appSecret={},type={}", customerId, code, appId, appSecret);
        WxCustomer customer = wxCustomerService.getWxCustomerById(customerId);
        if (customer == null) {
            return new RespEntity(RespCode.NO_RIGHT_OPERATION);
        }
        String openId = "";
        String accessToken = null;
        String nickName = "";
        String headImg = "";
        if ("false".equals(code)) {
            logger.info("code为false，直接返回不处理");
            return new RespEntity(RespCode.SUCCESS);
        }
        //首先判断code是否能在缓存中找到
        if (redisService.hasKey(code)) {
            openId = redisService.getValue(code);
            //获取用户名和头像
            Map<String, Object> userInfo = redisService.getHash(openId);
            if (userInfo != null && userInfo.get("name") != null && userInfo.get("headImg") != null) {
                nickName = (String) userInfo.get("name");
                headImg = (String) userInfo.get("headImg");
            }
        } else {
            if (!code.equals(fixedCode)) {
                try {
                    Map<String, String> map = wxUtilsService.getAccessTokenAndOpenId(code, appId, appSecret, customer.getType());
                    openId = map.get("openId");
                    accessToken = map.get("accessToken");
                    //根据accessToken获取个人信息
                    Map<String, Object> userInfo = wxUtilsService.getUserInfo(appId, appSecret, customer.getType(), accessToken, openId);
                    //保存openId和code对应关系，保存用户的头像和名称信息两天，与我们的免登录一致
                    redisService.setKey(code, openId, Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
                    redisService.setHash3(openId, userInfo, Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
                    nickName = (String) userInfo.get("name");
                    headImg = (String) userInfo.get("headImg");
                } catch (Exception e) {
                    return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
                }
            } else {
                openId = fixedOpenId;
            }
        }
        // 根据openId从wx_user表中查询数据
        logger.info("微信用户的openId：".concat(openId));
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        Integer wxUserId = addResult[1];
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        wxService.updateWxUserCustomerIdByWxUserId(wxUserId, customerId);
        redisService.setKey(token, String.valueOf(addResult[1]), 15, TimeUnit.DAYS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        jsonObject.put("nickName", nickName);
        jsonObject.put("headImage", headImg);
        logger.info("获取微信用户名称:".concat(nickName).concat("头像：").concat(headImg).concat("返回给前端token:").concat(token));
        jsonObject.put("type", Constants.PARENT_TYPE);
        //判断是否需要绑定，如果不需要，则给前端用户上次登录的类型
        if (addResult[0] == 0) {
            //获取用户手机号码
            WxUser wxUser = wxService.getWxUserByOpenId(openId);
            if (wxUser != null) {
                //根据手机号码获取用户类型
                String type = redisService.getValue(wxUser.getWxUserPhone().concat(Constants.WATER_USER_TYPE_PREFIX));
                if (type == null) {
                    logger.info("用户上次登录类型未存储，默认家长身份");
                    jsonObject.put("type", Constants.PARENT_TYPE);
                } else {
                    jsonObject.put("type", type);
                    logger.info("用户上次登录类型为：".concat(type));
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }


    /**
     * 校验微信用户(创维)
     */
    @GetMapping("/verifyWxUserCW")
    public RespEntity verifyWxUserCW(@RequestParam("code") String code) {
        logger.info("verifyWxUserCW code ={}" + code);
        String openId = "";
        if (!code.equals(fixedCode)) {
            try {
                openId = WxUtils.getOpenId4(code);
            } catch (Exception e) {
                return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
            }
        } else {
            openId = fixedOpenId;
        }
        // 根据openId从wx_user表中查询数据
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        Integer wxUserId = addResult[1];
        wxService.updateWxUserCustomerIdByWxUserId(wxUserId, CW_CUSTOMER);
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        redisService.setKey(token, String.valueOf(addResult[1]), Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        if (addResult[0] == 0) {
            //获取用户手机号码
            WxUser wxUser = wxService.getWxUserByOpenId(openId);
            if (wxUser != null) {
                //根据手机号码获取用户类型
                String type = redisService.getValue(wxUser.getWxUserPhone().concat(Constants.WATER_USER_TYPE_PREFIX));
                if (type == null) {
                    logger.info("用户上次登录类型未存储，默认家长身份");
                    jsonObject.put("type", Constants.PARENT_TYPE);
                } else {
                    jsonObject.put("type", type);
                    logger.info("用户上次登录类型为：".concat(type));
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }

    /**
     * 校验微信用户(小湃)
     */
    @GetMapping("/verifyWxUserXB")
    public RespEntity verifyWxUserXB(@RequestParam("code") String code) {
        logger.info("verifyWxUserXB code ={}" + code);
        String openId = "";
        if (!code.equals(fixedCode)) {
            try {
                openId = WxUtils.getOpenId5(code);
            } catch (Exception e) {
                return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
            }
        } else {
            openId = fixedOpenId;
        }
        // 根据openId从wx_user表中查询数据
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        Integer wxUserId = addResult[1];
        wxService.updateWxUserCustomerIdByWxUserId(wxUserId, XB_CUSTOMER);
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        redisService.setKey(token, String.valueOf(addResult[1]), Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        if (addResult[0] == 0) {
            //获取用户手机号码
            WxUser wxUser = wxService.getWxUserByOpenId(openId);
            if (wxUser != null) {
                //根据手机号码获取用户类型
                String type = redisService.getValue(wxUser.getWxUserPhone().concat(Constants.WATER_USER_TYPE_PREFIX));
                if (type == null) {
                    logger.info("用户上次登录类型未存储，默认家长身份");
                    jsonObject.put("type", Constants.PARENT_TYPE);
                } else {
                    jsonObject.put("type", type);
                    logger.info("用户上次登录类型为：".concat(type));
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }

    /**
     * 校验微信用户（喜马拉雅公众号）
     *
     * @param code 微信临时code（转openId用）
     * @return
     */
    @GetMapping("/verifyWxUserXM/{code}")
    public RespEntity verifyWxUserXM(@PathVariable("code") String code) {
        logger.info("verifyWxUserXM code = " + code);
        String openId = "";
        if (!code.equals(fixedCode)) {
            try {
                openId = WxUtils.getOpenId2(code);
            } catch (Exception e) {
                return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
            }
        } else {
            openId = fixedOpenId;
        }
        // 根据openId从wx_user表中查询数据
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        redisService.setKey(token, String.valueOf(addResult[1]), Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }


    /**
     * 校验微信用户（瑞翼公众号）
     *
     * @param code 微信临时code（转openId用）
     * @return
     */
    @GetMapping("/verifyWxUserRy/{code}")
    public RespEntity verifyWxUserRy(@PathVariable("code") String code) {
        logger.info("verifyWxUserRy code = " + code);
        String openId = "";
        //首先判断code是否能在缓存中找到
        if (redisService.hasKey(code)) {
            openId = redisService.getValue(code);
        } else {
            if (!code.equals(fixedCode)) {
                try {
                    openId = WxUtils.getOpenId3(code);
                    //保存openId和对应关系
                    redisService.setKey(code, openId, Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);
                } catch (Exception e) {
                    return new RespEntity(RespCode.CODE_2_OPENID_FAILED);
                }
            } else {
                openId = fixedOpenId;
            }
        }
        // 根据openId从wx_user表中查询数据
        int[] addResult = wxService.addOpenIdIfAbsent(openId);
        // 创建token 微信本身做了比较严格的校验，因此只存token-key(userId)即可
        String token = Tools.getRamdomStr();
        /*redisService.setKey(token, String.valueOf(addResult[1]), Constants.WXTOKEN_EXPIRE, TimeUnit.DAYS);*/
        redisService.setKey(token, String.valueOf(addResult[1]), 15, TimeUnit.DAYS);
        //获取微信用户名称和头像
        List<String> userInfo = WxUtils.getUserInfoRy(openId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("needBindingPhone", addResult[0]);
        jsonObject.put("token", token);
        jsonObject.put("nickName", userInfo.get(0));
        jsonObject.put("headImage", userInfo.get(1));
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }


    /**
     * 发送验证码
     *
     * @param request
     * @param phone    号码
     * @param areaCode 区域code
     * @return
     */
    @GetMapping("/sendVerifyCode/{phone}/{areaCode}")
    public RespEntity sendVerifyCode(@PathVariable("phone") String phone, @PathVariable("areaCode") String areaCode,
                                     HttpServletRequest request) {
        logger.info("sendVerifyCode : phone = {},areaCode = {}", phone, areaCode);
        // 发送短信
        String code = Tools.getRamdom6();
        if (areaCode.equals(Constants.CHINA_PHONE_AREA)) {
            SendToChina.sendVerifyCode(phone, code, 1);
        } else {
            SmsToInternational.sendVerifyCode(phone, code, 1);
        }
        redisService.setKey(Constants.WX_SMS_CODE_PREFIX + phone, code, 2, TimeUnit.MINUTES);
        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 发送验证码（沃特平台）
     *
     * @param request
     * @param phone    号码
     * @param areaCode 区域code
     * @return
     */
    @GetMapping("/sendVerifyCodeWater/{phone}/{areaCode}")
    public RespEntity sendVerifyCodeWater(@PathVariable("phone") String phone, @PathVariable("areaCode") String areaCode,
                                          HttpServletRequest request) {
        logger.info("sendVerifyCodeWater : phone = {},areaCode = {}", phone, areaCode);
        //判断是否是双重身份
        Teacher teacher = teacherService.getTeacherByPhone(phone);
        Map<String, Object> map = new HashMap<>();
        if (teacher == null) {
            map.put("type", Constants.PARENT_TYPE);
        } else {
            map.put("type", Constants.TEACHER_TYPE);
        }
        // 发送短信
        String code = Tools.getRamdom6();
        if (areaCode.equals(Constants.CHINA_PHONE_AREA)) {
            SendToChina.sendVerifyCode(phone, code, 1);
        } else {
            SmsToInternational.sendVerifyCode(phone, code, 1);
        }
        redisService.setKey(Constants.WX_SMS_CODE_PREFIX + phone, code, 2, TimeUnit.MINUTES);
        return new RespEntity(RespCode.SUCCESS, map);
    }

    /**
     * 绑定号码
     *
     * @param jsonObject
     * @param request
     * @return
     */
    @PostMapping("/bindingPhone")
    public RespEntity bindingPhone(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("bindingPhone : userId = {},param = {}", jsonObject);
        String code = jsonObject.getString("code");
        String phone = jsonObject.getString("phone");
        boolean flag = false;
/*        if (defaultPhone.equals(phone) && defaultVerifyCode.equals(code)) {
            flag = true;
        }*/
        if (!flag) {
            String redisCode = redisService.getValue(Constants.WX_SMS_CODE_PREFIX + phone);
            if (StringUtils.isBlank(redisCode)) {
                return new RespEntity(RespCode.VERIFY_CODE_EXPIRED);
            }
            if (!code.equals(redisCode)) {
                return new RespEntity(RespCode.VERIFY_CODE_ERROR);
            }
        }
        WxUser wxUser = wxService.getWxUserById(userId);
        if (wxUser != null) {
            String userPhone = wxUser.getWxUserPhone();
            if (StringUtils.isNotBlank(userPhone)) {
                return new RespEntity(RespCode.WX_USER_BINDED);
            }
        }
        int[] result = wxService.bindPhone(wxUser, phone, token,wxUser.getWxCustomer());
        //修改用户和学生绑定列表中的家长号码
        wxService.modifyBindingPhoneByUserId(result[1], phone);
        return new RespEntity(result[0] > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }


    /**
     * 绑定号码（沃特平台）
     *
     * @param jsonObject
     * @param request
     * @return
     */
    @PostMapping("/bindingPhoneWater")
    public RespEntity bindingPhoneWater(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("bindingPhone : userId = {},param = {}", jsonObject);
        String code = jsonObject.getString("code");
        String phone = jsonObject.getString("phone");
        Integer type = jsonObject.getInteger("type");
        if (type == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        //往缓存中存储一个用户类型，是教师还是家长
        redisService.setKey(phone.concat(Constants.WATER_USER_TYPE_PREFIX), type.toString(), 15, TimeUnit.DAYS);
        boolean flag = false;
        if (!flag) {
            String redisCode = redisService.getValue(Constants.WX_SMS_CODE_PREFIX + phone);
            if (StringUtils.isBlank(redisCode)) {
                return new RespEntity(RespCode.VERIFY_CODE_EXPIRED);
            }
            if (!code.equals(redisCode)) {
                return new RespEntity(RespCode.VERIFY_CODE_ERROR);
            }
        }
        WxUser wxUser = wxService.getWxUserById(userId);
        if (wxUser != null) {
            String userPhone = wxUser.getWxUserPhone();
            if (StringUtils.isNotBlank(userPhone)) {
                return new RespEntity(RespCode.WX_USER_BINDED);
            }
        }
        int[] result = wxService.bindPhone(wxUser, phone, token,wxUser.getWxCustomer());
        //修改用户和学生绑定列表中的家长号码
        wxService.modifyBindingPhoneByUserId(result[1], phone);
        return new RespEntity(result[0] > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 获取亲情号码的列表
     *
     * @param studentId
     * @return
     */
    @GetMapping("/getAffectionNumberList/{studentId}")
    public RespEntity getAffectionNumberList(@PathVariable("studentId") Integer studentId, HttpServletRequest request) {
        logger.info("getAffectionNumberList : studentId = " + studentId);
        List<DeviceWhiteList> whiteList = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        List<DeviceWhiteList> result = new ArrayList<>();
        if (whiteList != null && whiteList.size() > 0) {
            for (DeviceWhiteList white : whiteList) {
                if (white.getSequence() > 3 && white.getSequence() < 7) {
                    result.add(white);
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 编辑亲情号
     *
     * @return
     */
    @PostMapping("/modifyAffectionNumber")
    public RespEntity modifyAffectionNumber(@RequestBody DeviceWhiteList white, HttpServletRequest request) {
        logger.info("modifyAffectionNumber : white = " + white.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(white.getId());
        //根据设备id查找设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceInfo.getDeviceId());
        for (DeviceWhiteList w : list) {
            if ((w.getSequence() >= 4 && w.getSequence() <= 6) && w.getWhitePhone().equals(white.getWhitePhone()) && oldWhiteMess.getSequence() != w.getSequence()) {
                //该修改的手机号码已经是白名单号码了
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(deviceInfo.getStudentId(), userId);
        if (b) {
            //进行亲情号的编辑
            white.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发进行修改D
                DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
                deviceWhiteCall.setImei(deviceInfo.getImei());
                deviceWhiteCall.setCommandNumber(getCurTime());
                deviceWhiteCall.setSequence(oldWhiteMess.getSequence());
                deviceWhiteCall.setPhone(white.getWhitePhone());
                deviceWhiteCall.setName(white.getWhiteName());
                deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
                deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
                deviceWhiteCall.setIsAffection(1);
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateDeviceWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 添加亲情号（沃特校园）
     *
     * @return
     */
    @PostMapping("/addAffectionNumberWater/{studentId}/{name}/{number}/{sequence}")
    public RespEntity addAffectionNumberWater(@PathVariable("studentId") Integer studentId, @PathVariable("name") String name,
                                              @PathVariable("number") String number,
                                              @PathVariable("sequence") Integer sequence, HttpServletRequest request) {
        logger.info("addAffectionNumberWater : studentId = {},name = {},number = {},sequence={}  ", studentId.toString(), name, number, sequence);
        //判断sequence是否合理
        if (sequence > 6 || sequence < 4) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        for (DeviceWhiteList white : list) {
            if (white.getWhitePhone().equals(number) && (white.getSequence() >= 4 && white.getSequence() <= 6)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(1);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 添加亲情号(瑞翼)
     * 睿翼
     *
     * @return
     */
    @PostMapping("/addAffectionNumberRy/{studentId}/{name}/{number}")
    public RespEntity addAffectionNumberRy(@PathVariable("studentId") Integer studentId, @PathVariable("name") String name,
                                           @PathVariable("number") String number, HttpServletRequest request) {
        logger.info("addAffectionNumberRy : studentId = {},name = {},number = {}  " + studentId.toString() + name + number);
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        for (DeviceWhiteList white : list) {
            if (white.getWhitePhone().equals(number) && (white.getSequence() >= 4 && white.getSequence() <= 6)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //选取一个可用亲情号的序列号
            Integer sequence = getSequence(studentId);
            if (sequence == 0) {
                return new RespEntity(RespCode.UPLOAD_PEOPLE);
            }
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(1);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 添加亲情号(喜马拉雅)
     *
     * @return
     */
    @PostMapping("/addAffectionNumber/{studentId}/{name}/{number}")
    public RespEntity addAffectionNumber(@PathVariable("studentId") Integer studentId, @PathVariable("name") String name,
                                         @PathVariable("number") String number, HttpServletRequest request) {
        logger.info("addAffectionNumberXMLY : studentId = {},name = {},number = {}  " + studentId.toString() + name + number);
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        for (DeviceWhiteList white : list) {
            if (white.getWhitePhone().equals(number) && (white.getSequence() >= 4 && white.getSequence() <= 6)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //选取一个可用亲情号的序列号
            Integer sequence = getSequence(studentId);
            if (sequence == 0) {
                return new RespEntity(RespCode.UPLOAD_PEOPLE);
            }
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(1);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除亲情号
     *
     * @return
     */
    @DeleteMapping("/delAffectionNumber/{studentId}/{id}")
    public RespEntity delAffectionNumber(@PathVariable("studentId") Integer studentId, @PathVariable("id") Integer id,
                                         HttpServletRequest request) {
        logger.info("delAffectionNumber : studentId = {},id = {}  " + studentId.toString() + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //将亲情号的状态设置为待删除
            DeviceWhiteList white = new DeviceWhiteList();
            white.setId(id);
            white.setStatus(Constants.WHITE_PATTERN_STAY_DELETE);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delWhiteCall(deviceInfo.getImei(), getCurTime(), oldWhiteMess.getSequence(), isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取通讯录列表
     *
     * @param studentId
     * @return
     */
    @GetMapping("/getWhiteList/{studentId}")
    public RespEntity getWhiteList(@PathVariable("studentId") Integer studentId, HttpServletRequest request) {
        logger.info("getWhiteList : studentId = " + studentId);
        List<DeviceWhiteList> whiteList = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        List<DeviceWhiteList> result = new ArrayList<>();
        if (whiteList != null && whiteList.size() > 0) {
            for (DeviceWhiteList white : whiteList) {
                if (white.getSequence() > 6) {
                    result.add(white);
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, result);
    }


    /**
     * 编辑通讯录联系人
     *
     * @return
     */
    @PutMapping("/modifyLinkMan")
    public RespEntity modifyLinkMan(@RequestBody DeviceWhiteList white, HttpServletRequest request) {
        logger.info("modifyLinkMan : white = " + white.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(white.getId());
        //根据设备id查找设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceInfo.getDeviceId());
        for (DeviceWhiteList w : list) {
            if ((w.getSequence() >= 7) && w.getWhitePhone().equals(white.getWhitePhone()) && oldWhiteMess.getSequence() != w.getSequence()) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(deviceInfo.getStudentId(), userId);
        if (b) {
            //进行亲情号的编辑
            white.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发进行修改
                DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
                deviceWhiteCall.setImei(deviceInfo.getImei());
                deviceWhiteCall.setCommandNumber(getCurTime());
                deviceWhiteCall.setSequence(oldWhiteMess.getSequence());
                deviceWhiteCall.setPhone(white.getWhitePhone());
                deviceWhiteCall.setName(white.getWhiteName());
                deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
                deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
                deviceWhiteCall.setIsAffection(1);
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateDeviceWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);

    }


    /**
     * 添加通讯录联系人
     *
     * @return
     */
    @PostMapping("/addLinkMan/{studentId}/{name}/{number}")
    public RespEntity addLinkMan(@PathVariable("studentId") Integer studentId, @PathVariable("name") String name,
                                 @PathVariable("number") String number, HttpServletRequest request) {
        logger.info("addLinkMan : studentId = {},name = {},number = {}  " + studentId.toString() + name + number);
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(studentId);
        for (DeviceWhiteList white : list) {
            if ((white.getSequence() >= 7) && white.getWhitePhone().equals(number)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //选取一个可用联系人的序列号
            Integer sequence = getSequenceInLink(studentId);
            if (sequence == 0) {
                return new RespEntity(RespCode.UPLOAD_PEOPLE);
            }
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(0);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除联系人
     *
     * @return
     */
    @DeleteMapping("/delLinkMan/{studentId}/{id}")
    public RespEntity delLinkMan(@PathVariable("studentId") Integer studentId, @PathVariable("id") Integer id,
                                 HttpServletRequest request) {
        logger.info("delLinkMan : studentId = {},id = {}  " + studentId.toString() + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //将亲情号的状态设置为待删除
            DeviceWhiteList white = new DeviceWhiteList();
            white.setStatus(Constants.WHITE_PATTERN_STAY_DELETE);
            white.setId(id);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delWhiteCall(deviceInfo.getImei(), getCurTime(), oldWhiteMess.getSequence(), isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 绑定列表
     *
     * @param request
     * @return
     */
    @GetMapping("/bindingList")
    public RespEntity bindingList(HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("bindingList : userId = {}", userId);
        List<Map<String, Object>> studentList = wxService.getUserStudentList(userId);
        return new RespEntity(RespCode.SUCCESS, studentList);
    }

    /**
     * 修改设备imei
     *
     * @param imei
     * @param request
     * @return
     */
    @GetMapping("/modifyBindingMess/{imei}/{phone}")
    public RespEntity modifyBindingMess(@PathVariable("imei") String imei, @PathVariable("phone") String phone, HttpServletRequest request) {
        logger.info("/modifyBindingMess:imei={},phone={}" + imei + phone);
        int i = wxService.modifyPhoneByImei(imei, phone);
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /* *//**
     * 绑定学生
     *
     * @param jsonObject
     * @param request
     * @return
     *//*
    @PostMapping("/bindingStudent")
    public RespEntity bindingStudent(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("bindingStudent : userId = {}, param = {}", userId, jsonObject);
        String imei = jsonObject.getString("imei");
        String name = jsonObject.getString("name");
        String stuNo = jsonObject.getString("stuNo");
        return wxService.bindingStudent(userId, imei, name, stuNo);
    }*/

    /**
     * 删除绑定关系
     */
    @ApiOperation("删除绑定关系")
    @PutMapping("/unbindWeChatUser")
    public RespEntity unbindWeChatUser(@RequestBody UnbindWeChatUserDto data, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("unbindWeChatUser param={},userId={}", data.toString(), userId);
        Integer studentId = data.getStudentId();
        if (!wxUserStudentPermissionService.authUnbindStudent(userId, studentId, data.getWxUserId())) {
            return new RespEntity(RespCode.NO_RIGHT_OPERATION);
        }
        Integer rest = wxUserStudentPermissionService.unbindWxUserByStudentIdAndWxUserId(studentId, data.getWxUserId());
        return new RespEntity(rest > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 绑定学生
     *
     * @param data
     * @param request
     * @return
     */
    @ApiOperation("绑定学生")
    @PostMapping("/bindingStudent")
    public RespEntity bindingStudent(@RequestBody BindingStudentDto data, HttpServletRequest request) {
        logger.info("bindingStudent BindingStudentDto={}", data);
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        String imei = data.getImei();
        String name = data.getName();
        String stuNo = data.getStuNo();
        String type = data.getType();
        Integer userId = Integer.parseInt(redisUserId);
        //根据用户id查询用户信息
        WxUser wxUser = wxService.getWxUserById(userId);
        if (wxUser == null) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByImei(imei);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        WxCustomer wxCustomer = wxCustomerService.getWxCustomerById(wxUser.getWxCustomer());
        //校验设备是否属于这个客户
        if (wxCustomer != null && StringUtils.isNotBlank(wxCustomer.getCustomerCode())) {
            if (!deviceInfo.getOrgCode().startsWith(wxCustomer.getCustomerCode())) {
                return new RespEntity(RespCode.DEVICE_NOT_FOUND);
            }
        }
        if (wxCustomer != null && StringUtils.isNotBlank(type) && BindingStudentDto.NOT_STUNDET.equals(type)) {
            data = wxService.initDefaultCampusValue(wxCustomer, data);
            if (StringUtils.isNotBlank(wxCustomer.getOnOff()) && WxCustomer.OPEN.equals(wxCustomer.getOnOff())) {
                //此处走不需要平台提前绑定学生的代码
                Boolean rest = wxService.dealOpenStateBasicInformation(wxCustomer, data);
                if (!rest) {
                    return new RespEntity(RespCode.FAILED);
                }
            }
        }
        logger.info("bindingStudent : userId = {}, param = {}", userId, data.toString());
        //先校验学生是否录入平台
        List<Map<String, Object>> stuList = studentService.getStuByNameAndStuNo(name, stuNo);
        if (stuList == null || stuList.size() == 0) {
            return new RespEntity(RespCode.STUDENT_NOT_ENTER_PLATFORM);
        }
        //校验设备是否存在
        //筛选一个最有可能的学生id,同时校验了学生有没有被其他设备绑定
        /* Integer stuId = (Integer)stuList.get(0).get("student_id");*/
        Integer stuId = selectStudentId(stuList, imei, deviceInfo.getOrgCode());
        if (stuId == 0) {
            return new RespEntity(RespCode.STUDENT_DEVICE_NOT_MATCH);
        }
        //进行绑定校验,判断平台是否录入设备
        boolean flag = false;
        //设备已经导入平台，判断设备的类型
        if (deviceInfo.getDeviceType() != Constants.PLATFORM_DEVICE) {
            return new RespEntity(RespCode.DEVICE_NOT_BELONG_PLATFORM);
        }
        //校验设备是否已经绑定了学生
        if (deviceInfo.getStudentId() == null) {
/*            //校验设备组织是否在学校组织之下
            String deviceOrg = deviceInfo.getOrgCode();*/
            //将设备和学生进行绑定，并且允许用户绑定
            deviceInfo.setStudentId(stuId);
            int i = deviceInfoService.updateDeviceInfo(deviceInfo);
            if (i > 0) {
                flag = true;
            }
        } else if (deviceInfo.getStudentId().equals(stuId)) {
            //允许绑定
            flag = true;
        } else {
            //设备信息与学生信息不匹配
            return new RespEntity(RespCode.STUDENT_DEVICE_NOT_MATCH);
        }
        if (flag) {
            return wxService.bindingStudent(userId, imei, name, stuNo);
        }
        return new RespEntity(RespCode.FAILED);
    }


    /**
     * 解绑学生
     *
     * @param studentId
     * @param request
     * @return
     */
    @DeleteMapping("/unbindStudent/{studentId}")
    public RespEntity unbindStudent(@PathVariable("studentId") Integer studentId, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("unbindingStudent : userId = {}, studentId = {}", userId, studentId);
        //是否可以解绑
        boolean flag = false;
        //用于判断可以解绑时，该家长是否是管理员
        boolean isMan = false;
        //获取该学生的绑定家长列表
        List<Map<String, Object>> phoneList = wxService.bindStudentPhoneList(studentId);
        if (phoneList == null || phoneList.size() == 0) {
            return new RespEntity(RespCode.STUDENT_NO_BANDING_PARENTS);
        }
        if (phoneList.size() == 1) {
            //当仅有一个绑定家长时，可以直接操作
            flag = true;
            isMan = true;
        } else {
            //首先判断是否是管理员
            for (Map<String, Object> map : phoneList) {
                Integer wxUserId = (Integer) map.get("wx_user_id");
                Integer isManager = (Integer) map.get("is_manager");
                if (wxUserId.equals(userId)) {
                    flag = (isManager == 1 ? false : true);
                }
            }
        }
        if (flag) {
            //进行解绑操作
            studentService.updateStudentWxUserBindStatus(0, studentId);
            int i = wxService.unbindStudent(userId, studentId);
            //如果是管理员，得将学生和设备进行解绑
            if (isMan) {
                //如果是喜马拉雅的设备，还需给设备发送绑定关系
                DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
                if (deviceInfo != null && !StringUtils.isBlank(deviceInfo.getOrgCode())) {
                    if (deviceInfo.getOrgCode().contains("A01A03A05")) {
                        // 下发绑定关系指令
                        //设备在线则进行发送
                        //根据学生id获取年级、班级、学生名称、学校名称
                        Map<String, Object> bindingMap = new HashMap<>();
                        bindingMap.put("imei", deviceInfo.getImei());
                        bindingMap.put("status", Constants.DEVICE_UNBINDING);
                        bindingMap.put("commandNumber", getCurTime());
                        bindingMap.put("schoolName", "");
                        bindingMap.put("classesName", "");
                        bindingMap.put("studentName", "");
                        bindingMap.put("gradeName", "");
                        String s = JSONObject.toJSONString(bindingMap);
                        boolean isOnline = deviceOnline(deviceInfo.getImei());
                        //进行指令下发
                        commandSendUtils.sendBindingStatus(JSONObject.parseObject(s), Constants.WX_COMMAND_USER_ID, isOnline, false);
                    }
                }
                int i1 = deviceInfoService.unBindingStudentWithDevice(studentId);
            }
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        } else {
            return new RespEntity(RespCode.FIRST_REMOVE_MANAGER);
        }
    }

    /**
     * 查询学生列表
     *
     * @param request
     * @return
     */
    @GetMapping("/getStudentList")
    public RespEntity studentList(HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.USER_INDEX_EXPIRE);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("getStudentList : userId = {},token={}", userId,token);
        List<Map<String, Object>> studentList = wxService.getStudentList(userId);
        return new RespEntity(RespCode.SUCCESS, studentList);
    }

    /**
     * 查看课堂模式列表
     *
     * @param studentId
     * @return
     */
    @GetMapping("/getClassModeList/{studentId}")
    public RespEntity getClassModeList(@PathVariable("studentId") Integer studentId) {
        logger.info("getClassModeList : studentId = {}", studentId);
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        List<DeviceClassPattern> deviceClassPatternList = deviceClassPatternService.getDeviceClassesPatternByDeviceId(deviceInfo.getDeviceId());
        return new RespEntity(RespCode.SUCCESS, deviceClassPatternList);
    }


    /**
     * 添加课堂模式
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addClassMode")
    public RespEntity addClassMode(@RequestBody ClassModeVo data, HttpServletRequest request) {
        logger.info("addClassMode : data = {}", data.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        Integer sequence = getClassSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.CLASS_PATTERN_UPLOAD);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(data.getStuId(), userId);
        if (b) {
            //处理重复的开关
            String repeatTime = data.getList();
            String replace = repeatTime.replace(",", "");
            DeviceClassMode mode = new DeviceClassMode();
            mode.setEndTime(data.getEnd());
            mode.setImei(deviceInfo.getImei());
            mode.setSequence(sequence);
            mode.setCommandNumber(getCurTime());
            mode.setDeviceId(deviceInfo.getDeviceId());
            mode.setRepeatTime(replace);
            mode.setStartTime(data.getStart());
            mode.setOnOff(1);//默认开
            mode.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
            //在数据库添加一笔课堂模式数据
            int i = deviceClassPatternService.addDeviceClassPattern(mode);
            if (i > 0) {
                //指令下发进行添加课堂模式
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addClassMode(mode, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 修改课堂模式
     *
     * @param data
     * @param request
     * @return
     */
    @PutMapping("/modifyClassMode")
    public RespEntity modifyClassMode(@RequestBody ClassModeVo data, HttpServletRequest request) {
        logger.info("modifyClassMode : data = {}", data.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
       /* //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(data.getId());*/
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(data.getStuId(), userId);
        if (b) {
            //处理重复的开关
            String repeatTime = data.getList();
            String replace = repeatTime.replace(",", "");
            String commandNumber = getCurTime();
            DeviceClassMode mode = new DeviceClassMode();
            mode.setEndTime(data.getEnd());
            mode.setImei(deviceInfo.getImei());
            mode.setSequence(data.getSequence());
            mode.setCommandNumber(commandNumber);
            mode.setDeviceId(deviceInfo.getDeviceId());
            mode.setRepeatTime(replace);
            mode.setStartTime(data.getStart());
            mode.setOnOff(1);//默认开
            mode.setStatus(Constants.CLASSES_PATTERN_STAY_UPDATE);
            //修改课堂模式的状态为待修改
            int i = deviceClassPatternService.updateClassPatternStatus2(data.getId(), Constants.CLASSES_PATTERN_STAY_UPDATE, commandNumber);
            if (i > 0) {
                //指令下发进行添加课堂模式
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateClassMode(mode, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除课堂模式
     *
     * @param studentId
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delClassMode/{studentId}/{id}")
    public RespEntity delClassMode(@PathVariable("studentId") Integer studentId, @PathVariable("id") Integer id,
                                   HttpServletRequest request) {
        logger.info("delClassMode : studentId = {},id = {}  " + studentId.toString() + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //将课堂模式的状态设置为待删除
            String commandNumber = getCurTime();
            Integer i = deviceClassPatternService.updateClassPatternStatus2(id, Constants.CLASSES_PATTERN_STAY_DELETE, commandNumber);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delClassMode(deviceInfo.getImei(), commandNumber, classPattern.getSequence(), isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 根据id获取课堂模式
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getClassMode/{id}")
    public RespEntity getClassMode(@PathVariable("id") Integer id,
                                   HttpServletRequest request) {
        logger.info("getClassMode : studentId = {},id = {}  " + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(id);
        if (classPattern != null) {
            //处理课堂模式开关数据
            String repeatTime = classPattern.getRepeatTime();
            char[] chars = repeatTime.toCharArray();
            String s = ArrayUtils.toString(chars, ",");
            int length = s.length();
            String result = s.substring(1, length - 1);
            classPattern.setRepeatTime(result);
            return new RespEntity(RespCode.SUCCESS, classPattern);
        }
        return new RespEntity(RespCode.FAILED);
    }


    /**
     * 设置设备监听号码
     *
     * @param studentId
     * @param number
     * @param request
     * @return
     */
    @PutMapping("/setMonitorNumber/{studentId}/{number}")
    public RespEntity setMonitorNumber(@PathVariable("studentId") Integer studentId, @PathVariable("number") String number,
                                       HttpServletRequest request) {
        logger.info("setMonitorNumber : studentId = {},id = {}  " + studentId.toString() + number);
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        Boolean authMonitorNumber = deviceInfoService.authMonitorNumber(deviceInfo.getDeviceId(), number);
        if (!authMonitorNumber) {
            return new RespEntity(RespCode.MONITOR_PHONE_ERROR);
        }
        //判断设备是否在线
        boolean b1 = deviceOnline(deviceInfo.getImei());
        if (!b1) {
            return new RespEntity(RespCode.DEVICE_OFF_LINE);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //查找该设备的设置信息
            DeviceSetting setting = deviceInfoService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
            if (setting != null) {
                String commandNumber = getCurTime();
                setting.setMonitorNum(number);
                //修改设备设置信息
                int i = deviceInfoService.modifyDeviceInfoSetting(setting);
                if (i > 0) {
                    //进行指令下发
                    boolean b2 = commandSendUtils.setMonitorPhone(deviceInfo.getImei(), commandNumber, number, Constants.WX_COMMAND_USER_ID);
                    if (b2) {
                        return new RespEntity(RespCode.SUCCESS);
                    }
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 查询学生定位
     *
     * @param studentId
     * @param request
     * @return
     */
    @ApiOperation(value = "查询学生定位", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "studentId", value = "学生id", required = true, dataType = "int")
    })
    @GetMapping("/queryStudentLocation/{studentId}")
    public RespEntity queryStudentLocation(@PathVariable("studentId") Integer studentId,
                                           HttpServletRequest request) {
        logger.info("queryStudentLocation : studentId = {},id = {}  " + studentId.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据用户id查询绑定学生信息
        List<Map<String, Object>> studentList = wxService.getStudentList(userId);
        if (studentList == null || studentList.size() == 0) {
            return new RespEntity(RespCode.USER_NO_BANDING_STUDENT);
        }
        List<Integer> stuIdList = new ArrayList<>();
        //判断查询单个学生还是所有学生
        if (studentId == 0) {
            //查询所有
            for (Map<String, Object> map : studentList) {
                if ((Integer) map.get("status") != Constants.WX_DEVICE_NOT_FOUND) {
                    stuIdList.add((Integer) map.get("student_id"));
                }
            }
        } else {
            stuIdList.add(studentId);
        }
        //根据学生id获取学生的最新定位信息
        /*List<Map<String, Object>> locationList = deviceInfoService.getStudentPlaceByStudentId(stuIdList);*/
        List<Map<String, Object>> locationList= lastLocationDataService.getLastLocationByStudentIds(stuIdList);
        if (locationList != null && locationList.size() != 0) {
            //判断当前学生设备是否在线
            for (Map<String, Object> map : locationList) {
                String imei = (String) map.get("imei");
                boolean b = deviceOnline(imei);
                map.put("isOnline", b ? "在线" : "离线");
            }
            //去重数据每个学生只能有一笔定位数据
            List<Optional<Map<String, Object>>> result = locationList.stream().collect(Collectors.groupingBy(e -> e.get("device_id"))).values().stream().map(e -> {
                return e.stream().max((s1, s2) -> (Integer) s1.get("id") > (Integer) s2.get("id") ? 1 : -1);
            }).collect(Collectors.toList());
            List<Map<String, Object>> resultList = new ArrayList<>();
            result.stream().forEach(e -> {
                resultList.add(e.get());
            });
            logger.info("/返回给前端数据：data={}", resultList.toString());
            return new RespEntity(RespCode.SUCCESS, resultList);
        }
        return new RespEntity(RespCode.SUCCESS, locationList);
    }

    /**
     * 获取设备的轨迹
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getAttackByDeviceId/{deviceId}/{time}")
    public RespEntity getAttackByDeviceId(@PathVariable("deviceId") Integer deviceId, @PathVariable("time") Long time,
                                          HttpServletRequest request) {
        logger.info("getAttackByDeviceId : deviceId = {},id = {}  " + deviceId.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据设备id和时间获取设备当天的轨迹
        List<Map<String, Object>> trackList = locationService.getDeviceTrackByDeviceIdWx(deviceId, time);
        //数据去重
        ArrayList<Map<String, Object>> result = trackList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<Map<String, Object>>(
                        Comparator.comparing(o -> (Integer) o.get("id")))), ArrayList::new));
   /*     //对轨迹数据进行处理筛选
        List<Map<String, Object>> list = dealLocation(result);*/
        if (result != null && result.size() != 0) {
            return new RespEntity(RespCode.SUCCESS, result);
        }
        return new RespEntity(RespCode.SUCCESS, result);
    }


    /**
     * 根据学生id获取设备sos列表
     *
     * @param studentId
     * @param request
     * @return
     */
    @GetMapping("/getSOSList/{studentId}")
    public RespEntity getSOSList(@PathVariable("studentId") Integer studentId,
                                 HttpServletRequest request) {
        logger.info("getSOSList : studentId = {},id = {}  " + studentId.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //获取sos列表
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceInfo.getDeviceId());
        return new RespEntity(RespCode.SUCCESS, sosList);
    }


    /**
     * 修改SOS信息
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifySOSMessage")
    public RespEntity modifySOSMessage(@RequestBody SOSListVO data, HttpServletRequest request) {
        logger.info("modifySOSMessage : data = {}", data.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStudentId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(data.getStudentId(), userId);
        if (b) {
            //获取该设备所有的sos号码列表,判断是否重复
            List<DeviceSOSList> list = logService.getSOSListByDeviceId(deviceInfo.getDeviceId());
            for (DeviceSOSList sos : list) {
                if (sos.getSosPhone().equals(data.getPhone()) && sos.getSequence() != data.getSequence()) {
                    return new RespEntity(RespCode.NUMBER_HAD_USED);
                }
            }
            //获取流水号
            String commandNumber = getCurTime();
            DeviceSOSList sos = new DeviceSOSList();
            sos.setDeviceId(deviceInfo.getDeviceId());
            sos.setCommandNumber(commandNumber);
            sos.setSequence(data.getSequence());
            sos.setSosName(data.getName());
            sos.setSosPhone(data.getPhone());
            sos.setStatus(Constants.DEVICE_SOS_STAY_UPDATE);
          /*  //修改SOS号码的状态为待修改
            int i = logService.updateSosListStatus(data.getId(), Constants.DEVICE_SOS_STAY_UPDATE, commandNumber);*/
            //修改SOS号码的状态为待修改同时修改数据库内容
            Integer i = logService.updateSosListData(data, Constants.DEVICE_SOS_STAY_UPDATE, commandNumber);
            //修改SOS号码的状态为待修改
            if (i > 0) {
                //指令下发进行修改SOS信息
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> modifySOSList = getModifySetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(modifySOSList, deviceInfo.getImei(), commandNumber, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加SOS信息
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addSOSList")
    public RespEntity addSOSList(@RequestBody SOSListVO data, HttpServletRequest request) {
        logger.info("addSOSList : data = {}", data.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStudentId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        Integer sequence = getSosSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.SOS_NUMBER_UPLOAD);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(data.getStudentId(), userId);
        if (b) {
            //获取该设备所有的sos号码列表,判断是否重复
            List<DeviceSOSList> list = logService.getSOSListByDeviceId(deviceInfo.getDeviceId());
            for (DeviceSOSList sos : list) {
                if (sos.getSosPhone().equals(data.getPhone())) {
                    return new RespEntity(RespCode.NUMBER_HAD_USED);
                }
            }
            String commandNumber = getCurTime();
            DeviceSOSList sos = new DeviceSOSList();
            sos.setDeviceId(deviceInfo.getDeviceId());
            sos.setCommandNumber(commandNumber);
            sos.setSequence(sequence);
            sos.setSosName(data.getName());
            sos.setSosPhone(data.getPhone());
            sos.setStatus(Constants.DEVICE_SOS_STAY_ADD);
            //在数据库添加一笔SOS号码信息
            int i = logService.insertSosNumberList(sos);
            if (i > 0) {
                //指令下发进行添加SOS号码
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> sosList = getAddSetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(sosList, deviceInfo.getImei(), commandNumber, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除SOS信息
     *
     * @param studentId
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delSOSMess/{studentId}/{id}")
    public RespEntity delSOSMess(@PathVariable("studentId") Integer studentId, @PathVariable("id") Integer id,
                                 HttpServletRequest request) {
        logger.info("delSOSMess : studentId = {},id = {}  " + studentId.toString() + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找SOS信息
        DeviceSOSList sosMess = logService.getDeviceSOSMessById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(studentId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(studentId, userId);
        if (b) {
            //将sos号码信息的状态设置为待删除
            String commandNumber = getCurTime();
            Integer i = logService.updateSosListStatus(id, Constants.DEVICE_SOS_DELETE, commandNumber);
            if (i > 0) {
                DeviceSOSList sos = new DeviceSOSList();
                sos.setDeviceId(deviceInfo.getDeviceId());
                sos.setCommandNumber(commandNumber);
                sos.setSequence(sosMess.getSequence());
                sos.setSosName("");
                sos.setSosPhone("");
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> sosList = getDelSetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(sosList, deviceInfo.getImei(), commandNumber, isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 根据id获取sos信息
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getSOSMessById/{id}")
    public RespEntity getSOSMessById(@PathVariable("id") Integer id,
                                     HttpServletRequest request) {
        logger.info("getSOSMessById : studentId = {},id = {}  " + id.toString());
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找SOS记录
        DeviceSOSList sos = logService.getDeviceSOSMessById(id);
        return new RespEntity(sos == null ? RespCode.FAILED : RespCode.SUCCESS, sos);
    }

    /**
     * 退出登录
     *
     * @param request
     * @return
     */
    @PutMapping("/logout")
    public RespEntity logout(HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        int i = wxService.clearBind(userId);
        //清除Token
        redisService.deleteKey(token);
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 获取绑定学生的号码列表
     *
     * @param studentId
     * @param request
     * @return
     */
    @GetMapping("/bindStudentPhoneList/{studentId}")
    public RespEntity bindStudentPhoneList(@PathVariable("studentId") Integer studentId, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("getBindPhoneList : userId = {},studentId = {}" + userId, studentId);
        List<Map<String, Object>> phoneList = wxService.bindStudentPhoneList(studentId);
        // 防止openId未绑定号码导致查询的List中phone有null元素
        Iterator iterator = phoneList.iterator();
        Map<String, Object> firstMap = new HashMap<>();
        boolean ifMan = false;
        for (Map<String, Object> map : phoneList) {
            Integer isMan = (Integer) map.get("is_manager");
            Integer wx_user_id = (Integer) map.get("wx_user_id");
            if (wx_user_id.equals(userId) && isMan == 1) {
                ifMan = true;
            }
            if (isMan == 1) {
                firstMap = map;
            }
        }
        while (iterator.hasNext()) {
            Map<String, Object> map = (Map<String, Object>) iterator.next();
            String phone = (String) map.get("wx_user_phone");
            if (StringUtils.isBlank(phone)) {
                iterator.remove();
            }
        }
        Integer needShow = ifMan ? 1 : 0;
        List<Map<String, Object>> resultList = new ArrayList<>();
        firstMap.put("need_show", needShow);
        resultList.add(0, firstMap);
        for (Map<String, Object> map : phoneList) {
            Integer wx_user_id = (Integer) map.get("wx_user_id");
            Integer wx_user_id2 = (Integer) firstMap.get("wx_user_id");
            if (wx_user_id != wx_user_id2) {
                map.put("need_show", needShow);
                resultList.add(map);
            }
        }
        return new RespEntity(RespCode.SUCCESS, resultList);
    }

    /**
     * 转让管理员
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/transferManager/{id}")
    public RespEntity transferManager(@PathVariable("id") Integer id, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("transferManager : id = {}" + id.toString());
        //根据id查找到绑定记录
        Map<String, Object> map = wxService.getBindingById(id);
        Integer wx_user = (Integer) map.get("wx_user");
        Integer stuId = (Integer) map.get("student");
        //管理员转让
        Integer i = wxService.changeManger(stuId, userId, wx_user);
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 授权和取消授权
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/giveAuthority/{id}")
    public RespEntity giveAuthority(@PathVariable("id") Integer id, HttpServletRequest request) {
        logger.info("giveAuthority : id = {}" + id.toString());
        //根据id获取绑定记录
        Map<String, Object> map = wxService.getBindingById(id);
        Integer is_authorization = (Integer) map.get("is_authorization");
        //授权
        Integer status = (is_authorization == 1 ? 0 : 1);
        Integer i = wxService.changeAuthority(id, status);
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }


    /**
     * 立即定位
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getImmediatelyLocation/{stuId}")
    public RespEntity getImmediatelyLocation(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("getImmediatelyLocation : stuId = {}" + stuId.toString());
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        List<Integer> stuIdList = new ArrayList<>();
        if (stuId == 0) {
            //给所有学生进行立即定位
            //根据用户id查询绑定学生信息
            List<Map<String, Object>> studentList = wxService.getStudentList(userId);
            if (studentList == null || studentList.size() == 0) {
                return new RespEntity(RespCode.USER_NO_BANDING_STUDENT);
            }
            studentList.stream().forEach(e -> {
                stuIdList.add((Integer) e.get("student_id"));
            });
        } else {
            stuIdList.add(stuId);
        }
        //根据学生id获取设备imei
        List<String> imeiList = studentService.getImeiListByStuIdList(stuIdList);
        Integer success = 0;
        Integer all = imeiList.size();
        Integer offLine = 0;
        Integer fail = 0;
        if (stuId == 0) {
            for (String imei : imeiList) {
                if (StringUtils.isBlank(imei)) {
                    fail++;
                    continue;
                }
                String commandNumber = getCurTime();
                boolean isOnline = deviceOnline(imei);
                if (isOnline) {
                    //设备在线则进行指令下发
                    boolean b = commandSendUtils.queryDeviceLocation(imei, commandNumber, Constants.WX_COMMAND_USER_ID, isOnline, false);
                    if (b) {
                        success++;
                        continue;
                    }
                    fail++;
                    continue;
                }
                offLine++;
                continue;
            }
            logger.info("/immediatelyLocation:all = {} ,success= {},offLine = {},fail = {}", all.toString(), success.toString(), offLine.toString(), fail.toString());
            return new RespEntity(RespCode.SUCCESS);
        } else {
            String imei = imeiList.get(0);
            String commandNumber = getCurTime();
            boolean isOnline = deviceOnline(imei);
            if (isOnline) {
                //设备在线则进行指令下发
                boolean b = commandSendUtils.queryDeviceLocation(imei, commandNumber, Constants.WX_COMMAND_USER_ID, isOnline, false);
                if (b) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.DEVICE_OFF_LINE);
        }
    }

    /**
     * 根据学生id查找电子围栏
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getFenceInfoByStuId/{stuId}")
    public RespEntity getFenceInfoByStuId(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("getFenceInfoByStuId : stuId = {}" + stuId.toString());
        //根据学生id获取电子围栏
        List<FenceInfo> fenceList = fenceInfoService.getFenceInfoListByStuId(stuId);
        return new RespEntity(RespCode.SUCCESS, fenceList);
    }

    /**
     * 根据id删除围栏
     *
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delFenceById/{id}")
    public RespEntity delFenceById(@PathVariable("id") Integer id, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("getFenceInfoByStuId : id = {}" + id.toString());
        //根据围栏id查询学生id
        FenceInfo fenceInfo = fenceInfoService.getFenceInfoById(id);
        if (fenceInfo == null || fenceInfo.getStudent_id() == null) {
            return new RespEntity(RespCode.FENCE_NOT_FOUND);
        }
        //鉴权
        boolean b = veryAuthentication(fenceInfo.getStudent_id(), userId);
        if (b) {
            //根据id删除围栏
            Integer i = fenceInfoService.deleteFenceInfo(id);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 修改围栏
     *
     * @param fenceInfo
     * @param request
     * @return
     */
    @PutMapping("/modifyFence")
    public RespEntity modifyFence(@RequestBody FenceInfo fenceInfo, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("modifyFence : fenceInfo = {}" + fenceInfo.toString());
        //鉴权
        boolean b = veryAuthentication(fenceInfo.getStudent_id(), userId);
        if (b) {
            //判断围栏名称是否重复（对于一个学生而言）
            //根据学生id查找这个学生的所有围栏
            List<FenceInfo> fenceList = fenceInfoService.getFenceInfoListByStuId(fenceInfo.getStudent_id());
            for (FenceInfo fence : fenceList) {
                if ((!fence.getFence_id().equals(fenceInfo.getFence_id())) && fence.getFence_name().equals(fenceInfo.getFence_name())) {
                    return new RespEntity(RespCode.FENCE_NAME_REPEAT);
                }
            }
            //修改围栏信息
            Integer i = fenceInfoService.modifyWxFenceInfo(fenceInfo);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 新增围栏
     *
     * @param fenceInfo
     * @param request
     * @return
     */
    @PostMapping("/addFenceInfo")
    public RespEntity addFenceInfo(@RequestBody FenceInfo fenceInfo, HttpServletRequest request) {
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        logger.info("addFenceInfo : fenceInfo = {}" + fenceInfo.toString());
        //鉴权
        boolean b = veryAuthentication(fenceInfo.getStudent_id(), userId);
        if (b) {
            //判断围栏名称是否重复（对于一个学生而言）
            //根据学生id查找这个学生的所有围栏
            List<FenceInfo> fenceList = fenceInfoService.getFenceInfoListByStuId(fenceInfo.getStudent_id());
            for (FenceInfo fence : fenceList) {
                if (fence.getFence_name().equals(fenceInfo.getFence_name())) {
                    return new RespEntity(RespCode.FENCE_NAME_REPEAT);
                }
            }
            //新增围栏
            Integer i = fenceInfoService.addWxFence(fenceInfo);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取通话记录
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getCallRecord/{stuId}/{num}")
    public RespEntity getCallRecord(@PathVariable("stuId") Integer stuId, @PathVariable("num") Integer num, HttpServletRequest request) {
        logger.info("getCallRecord : stuId = {}" + stuId.toString());
        //根据学生id获取通话记录
        List<Map<String, Object>> callList = logService.getCallRecordByStuId(stuId, num);
        return new RespEntity(RespCode.SUCCESS, callList);
    }

    /**
     * 获取一个学生的所有存在的告警类型（瑞翼）
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getWarningType/{stuId}")
    public RespEntity getWarningType(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("getWarningType : stuId = {}" + stuId.toString());
        //根据学生id获取该学生的所有存在的告警类型
        List<Map<String, Object>> warnTypeList = logService.getWarningTypeByStuId(stuId);
        //去重，如果有一个类型有两笔相同时间的告警类型，取id最大的那个
        List<Optional<Map<String, Object>>> collect = warnTypeList.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        List<Map<String, Object>> result = new ArrayList<>();
        List<Map<String, Object>> fenceWarn = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //拼凑返回的信息
        collect.stream().forEach(e -> {
            Map<String, Object> map = e.get();
            Integer type = (Integer) map.get("warning_type");
            //暂时不做关机告警记录的显示，6为关机告警记录
            map.put("time", sdf.format(new Date((Long) map.get("warning_time"))));
            if (type == Constants.SOS_WARNING_TYPE) {
                map.put("warnName", "SOS提醒");
                map.put("content", "您的设备".concat("于").concat((String) map.get("address")).concat("拨打SOS号码"));
                result.add(map);
            } else if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                map.put("warnName", "低电量提醒");
                map.put("content", "您的设备".concat("电量不足15%，请及时充电"));
                result.add(map);
            } else if (type == Constants.ENTER_FENCE_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                result.add(map);
            } else if (type == Constants.LEFT_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                result.add(map);
            }
        });
        //合并出围栏和入围栏信息
        List<Optional<Map<String, Object>>> result2 = result.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        return new RespEntity(RespCode.SUCCESS, result2);
    }

    /**
     * 获取一个学生的所有存在的告警类型（沃特平台）
     *
     * @param stuId
     * @param request
     * @return
     */
    @ApiOperation("根据学生id查询告警记录")
    @GetMapping("/getWarningTypeWater/{stuId}")
    public RespEntity getWarningTypeWater(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("getWarningTypeWater : stuId = {}" + stuId.toString());
        //根据学生id获取该学生的所有存在的告警类型
        List<Map<String, Object>> warnTypeList = logService.getWarningTypeByStuId(stuId);
        //根据学生id查询设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //去重，如果有一个类型有两笔相同时间的告警类型，取id最大的那个
        List<Optional<Map<String, Object>>> collect = warnTypeList.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        List<Map<String, Object>> result = new ArrayList<>();
        List<Map<String, Object>> fenceWarn = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //查询告警类型消息状态
        Map<String, Object> isNewMap = redisService.getHash(Constants.WARN_TYPE_IS_NEW.concat(stuId.toString()));
        boolean flag = isNewMap == null ? true : false;
        //拼凑返回的信息
        collect.stream().forEach(e -> {
            Map<String, Object> map = e.get();
            Integer type = (Integer) map.get("warning_type");
            Long time = (Long) map.get("warning_time");
            map.put("time", sdf.format(new Date((Long) map.get("warning_time"))));
            Long oldTime = 0l;
            if (type == Constants.SOS_WARNING_TYPE) {
                map.put("warnName", "SOS提醒");
                map.put("content", "您的设备".concat("于").concat((String) map.get("address")).concat("拨打SOS号码"));
                if (!flag && isNewMap.get("sos") != null) {
                    oldTime = (Long) isNewMap.get("sos");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                map.put("warnName", "低电量提醒");
                map.put("content", "您的设备".concat("电量不足15%，请及时充电"));
                if (!flag && isNewMap.get("lowBattery") != null) {
                    oldTime = (Long) isNewMap.get("lowBattery");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constants.ENTER_FENCE_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                if (!flag && isNewMap.get("fence") != null) {
                    oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constants.LEFT_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                if (!flag && isNewMap.get("fence") != null) {
                    oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                map.put("warnName", "关机提醒");
                map.put("content", "您的设备".concat("已关机"));
                if (!flag && isNewMap.get("shutdown") != null) {
                    oldTime = (Long) isNewMap.get("shutdown");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                map.put("warnName", "开机提醒");
                map.put("content", "您的设备".concat("已开机"));
                if (!flag && isNewMap.get("powerOn") != null) {
                    oldTime = (Long) isNewMap.get("powerOn");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                //如果是有新消息，则查询新消息数目
                if ((boolean) map.get("isNew")) {
                    //根据上次查看时间和本次点击时间查询新消息数目
                    int i = logService.selectCountByTypeAndTime(deviceInfo.getDeviceId(), type, oldTime);
                    map.put("newNum", i);
                }
                result.add(map);
            }
        });
        //合并出围栏和入围栏信息
        List<Optional<Map<String, Object>>> result2 = result.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
/*        //结果进行固定位置编排
        List<Map<String, Object>> list = changePlace(result2);*/
        //根据学生id获取学校id和班级id
        Map<String, Object> map = studentService.getSchoolIdAndClassIdByStuId(stuId);
        Integer classId = (Integer) map.get("classes_id");
        Integer schoolId = (Integer) map.get("id");
        //查询出最新的咨询或者通知
        Long time1 = informationService.getBiggestTimeBySchoolId(schoolId);
        Long time2 = notificationService.getLatestNotificationTimeByClassId(classId);
        if (time1 != null || time2 != null) {
            Map<String, Object> newsMap = new HashMap<>();
            newsMap.put("warnName", "校园通知");
            newsMap.put("content", "您有一条新的校园通知，请点击查看");
            newsMap.put("warning_type", 0);
            if (time1 != null && time2 == null) {
                newsMap.put("warning_time", time1);
            } else if (time1 == null && time2 != null) {
                newsMap.put("warning_time", time2);
            } else {
                /*  newsMap.put("warning_time", sdf.format(new Date(time1 > time2 ? time1 : time2)));*/
                newsMap.put("warning_time", time1 > time2 ? time1 : time2);
            }
            if (!flag && isNewMap.get("school") != null) {
                Long oldTime = (Long) isNewMap.get("school");
                boolean isNew = (Long) newsMap.get("warning_time") > oldTime ? true : false;
                newsMap.put("isNew", isNew);
            } else {
                newsMap.put("isNew", true);
            }
            result2.add(Optional.of(newsMap));
        }
        return new RespEntity(RespCode.SUCCESS, result2);
    }

    /**
     * 根据类型和时间去更新一个类型是否是最新记录
     *
     * @param type
     * @param isNew
     * @param time
     * @param request
     * @return
     */
    @GetMapping("/setMessIsNew/{type}/{isNew}/{time}/{stuId}")
    public RespEntity setMessIsNew(@PathVariable Integer type, @PathVariable Boolean isNew,
                                   @PathVariable Long time, @PathVariable Integer stuId,
                                   HttpServletRequest request) {
        logger.info("setMessIsNew : type = {},isNew = {},time = {}", type.toString(), isNew.toString(), time.toString());
        if (isNew) {
            //如果是新消息则修改存储时间
            String key = Constants.WARN_TYPE_IS_NEW.concat(stuId.toString());
            boolean b = redisService.hasKey(key);
            if (!b) {
                Map<String, Object> map = new HashMap<>();
                String name = "";
                if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                    name = "lowBattery";
                } else if (type == Constants.SOS_WARNING_TYPE) {
                    name = "sos";
                } else if (type == 5) {
                    name = "fence";
                } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                    name = "powerOn";
                } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                    name = "shutdown";
                } else if (type == 0) {
                    name = "school";
                }
                map.put(name, time);
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            } else {
                Map<String, Object> map = redisService.getHash(key);
                if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                    map.put("lowBattery", time);
                } else if (type == Constants.SOS_WARNING_TYPE) {
                    map.put("sos", time);
                } else if (type == 5) {
                    map.put("fence", time);
                } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                    map.put("powerOn", time);
                } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                    map.put("shutdown", time);
                } else if (type == 0) {
                    map.put("school", time);
                }
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            }
        }
        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 获取告警记录
     *
     * @param stuId
     * @param request
     * @return
     */
    @GetMapping("/getWarningList/{stuId}/{warnType}/{num}")
    public RespEntity getWarningList(@PathVariable Integer stuId, @PathVariable Integer warnType,
                                     @PathVariable Integer num, HttpServletRequest request) {
        logger.info("getWarningList : stuId = {},warnType = {}", stuId.toString(), warnType.toString());
        //根据学生id和类型查询告警记录
        List<Map<String, Object>> warnList = logService.getWarningListByStuIdAndType(stuId, warnType, num);
        warnList.stream().forEach(e -> {
            Integer type = (Integer) e.get("warning_type");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            e.put("time", sdf.format(new Date((Long) e.get("warning_time"))));
            if (type == Constants.SOS_WARNING_TYPE) {
                e.put("warnName", "SOS提醒");
                e.put("content", "您的设备".concat("于").concat((String) e.get("address")).concat("拨打SOS号码"));
            } else if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                e.put("warnName", "低电量提醒");
                e.put("content", "您的设备".concat("电量不足15%，请及时充电"));
            } else if (type == Constants.ENTER_FENCE_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constants.LEFT_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                e.put("warnName", "关机提醒");
                e.put("content", "您的设备".concat("已关机"));
            } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                e.put("warnName", "开机提醒");
                e.put("content", "您的设备".concat("已开机"));
            }
        });
        return new RespEntity(RespCode.SUCCESS, warnList);
    }


    /**
     * 根据学生id和时间查找一天的班级通知
     *
     * @return
     */
    @GetMapping("/getNotificationByTime/{stuId}/{time}/{count}")
    public RespEntity getNotificationByTime(@PathVariable("stuId") Integer stuId, @PathVariable("time") Long time, @PathVariable("count") Integer count) {
        logger.info("/getNotificationByTime:stuId={},time={}", stuId.toString(), time.toString());
        Map<String, Object> student = studentService.getStudentByStuId(stuId);
        if (student == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        Integer classId = (Integer) student.get("classes_id");
        List<Notification> resultList = notificationService.getNotificationByTimeAndClassId(classId, time, count);
        return new RespEntity(RespCode.SUCCESS, resultList);
    }

    /**
     * 根据学生id和时间查找一天的校园资讯
     *
     * @return
     */
    @GetMapping("/getInformationByTime/{stuId}/{time}/{count}")
    public RespEntity getInformationByTime(@PathVariable("stuId") Integer stuId, @PathVariable("time") Long time, @PathVariable("count") Integer count) {
        logger.info("/getInformationByTime:stuId={},time={}", stuId.toString(), time.toString());
        Map<String, Object> map = studentService.getSchoolIdAndClassIdByStuId(stuId);
        if (map == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        Integer schoolId = (Integer) map.get("id");
        List<Information> resultList = informationService.getInformationByTimeAndSchoolId(schoolId, time, count);
        return new RespEntity(RespCode.SUCCESS, resultList);
    }

    /**
     * 根据id获取资讯信息
     *
     * @param id
     * @return
     */
    @GetMapping("/getInformationById/{id}")
    public RespEntity getInformationById(@PathVariable Integer id) {
        logger.info("/getInformationById:id={}", id.toString());
        //根据id获取资讯信息
        Information information = informationService.getInformationById(id);
        if (information == null) {
            return new RespEntity(RespCode.NO_DATA);
        }
        return new RespEntity(RespCode.SUCCESS, information);
    }

    /**
     * 根据id获取通知信息
     *
     * @param id
     * @return
     */
    @GetMapping("/getNotificationById/{id}")
    public RespEntity getNotificationById(@PathVariable Integer id) {
        logger.info("/getNotificationById:id={}", id.toString());
        //根据id获取资讯信息
        Notification notification = notificationService.getNotificationById(id);
        if (notification == null) {
            return new RespEntity(RespCode.NO_DATA);
        }
        return new RespEntity(RespCode.SUCCESS, notification);
    }

    /**
     * 获取一个老师管理的班级
     *
     * @param
     * @return
     */
    @GetMapping("/getClassName")
    public RespEntity getClassName(HttpServletRequest request) {
        logger.info("/getClassName");
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        //根据用户id查询用户信息
        WxUser wxUser = wxService.getWxUserById(userId);
        //根据手机号码查询一个老师管理的班级信息
        String classes = wxService.getClassesMessByUserId(userId);
        if (StringUtils.isBlank(classes)) {
            return new RespEntity(RespCode.NO_DATA);
        }
        String[] classList = classes.split(",");
        List<Integer> classIdList = new ArrayList<>();
        for (String id : classList) {
            classIdList.add(Integer.valueOf(id));
        }
        //根据id获取班级信息
        List<Map<String, Object>> messList = wxService.getClassNameByClassIdList(classIdList);
        List<Map<String, Object>> result = new ArrayList<>();
        messList.stream().forEach(e -> {
            String className = (String) e.get("classes_name");
            String gradeName = (String) e.get("grade_name");
            Integer classId = (Integer) e.get("classes_id");
            Map<String, Object> map = new HashMap<>();
            map.put("name", gradeName.concat(className));
            map.put("classId", classId);
            result.add(map);
        });
        return new RespEntity(RespCode.SUCCESS, result);
    }


    /**
     * 根据班级id和时间查找一天的班级通知
     *
     * @return
     */
    @GetMapping("/getNotificationByTimeAndClassId/{classId}/{time}/{count}")
    public RespEntity getNotificationByTimeAndClassId(@PathVariable("classId") Integer classId, @PathVariable("time") Long time, @PathVariable("count") Integer count) {
        logger.info("/getNotificationByTimeAndClassId:classId={},time={}", classId.toString(), time.toString());
        List<Notification> resultList = notificationService.getNotificationByTimeAndClassId(classId, time, count);
        return new RespEntity(RespCode.SUCCESS, resultList);
    }


    /**
     * 发布通知
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addNotificationWx")
    public RespEntity addNotificationWx(@RequestBody Notification data, HttpServletRequest request) {
        logger.info("/addNotificationWx:data={}", data.toString());
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer userId = Integer.parseInt(redisUserId);
        //判断班级是否存在
        Integer classesId = classService.getClassIdByClassId(data.getClassId());
        if (classesId == null) {
            return new RespEntity(RespCode.CLASS_NOT_EXIST);
        }
        //根据用户id获取老师名称
        String teacherName = wxService.getTeacherNameByUserId(userId);
        if (StringUtils.isBlank(teacherName)) {
            return new RespEntity(RespCode.TEACHER_NAME_NOT_SET);
        }
        data.setCreateTime(System.currentTimeMillis());
        data.setUserId(userId);
        data.setUserName(teacherName);
        //根据班级id查找年级学校信息
        Map<String, Object> map = notificationService.getSchoolAndGradeMessByClassId(data.getClassId());
        data.setClassName((String) map.get("classes_name"));
        data.setGradeId((Integer) map.get("grade_id"));
        data.setGradeName((String) map.get("grade_name"));
        data.setSchoolId((Integer) map.get("school_id"));
        data.setType(1);//1表示微信用户
        //新增一笔通知
        /*data.setContent(data.getContent().replace("\n", "<br/>"));*/
        int i = notificationService.addNotificationWx(data);
        if (i > 0) {
            //获取需要推送的openId集合
            List<Map<String, Object>> messList = wxService.getOpenIdAndStuNameListByClassId(classesId);
            WxUser wxUser = wxService.getWxUserById(userId);
            List<String> listStr = new ArrayList<>();
            if (wxUser != null && wxUser.getWxCustomer() != null) {
                messList.stream().forEach(e -> {
                    String openId = (String) e.get("open_id");
                    String stuName = (String) e.get("student_name");
                    if (openId != null && stuName != null) {
                        listStr.add(openId.concat(",").concat(stuName).concat(",").concat(String.valueOf(wxUser.getWxCustomer())));
                    }
                });
            } else {
                messList.stream().forEach(e -> {
                    String openId = (String) e.get("open_id");
                    String stuName = (String) e.get("student_name");
                    if (openId != null && stuName != null) {
                        listStr.add(openId.concat(",").concat(stuName));
                    }
                });
            }
            /* List<String> openIdList =new ArrayList<>();
            for (int j=0;j<8;j++){
                openIdList.add("obdQT6E9yFappDV4etV7quwxYCcA");
            }*/
            PushMessDataVO pushMessDataVO = new PushMessDataVO();
            pushMessDataVO.setFlag(Constants.PUSH_NOTIFICATION);
            pushMessDataVO.setClassName(data.getGradeName().concat(data.getClassName()));
            pushMessDataVO.setContent(data.getContent());
            pushMessDataVO.setId(data.getId());
            pushMessDataVO.setTitle(data.getTitle());
            pushMessDataVO.setUserName(data.getUserName());
            pushMessDataVO.setTime(System.currentTimeMillis());
            logger.info("推送的内容为：data={}", pushMessDataVO.toString());
            //进行微信推送
            ForkJoinPushTask task = new ForkJoinPushTask(pushMessDataVO, listStr, 0);
            ForkJoinPoolUtils.forkJoinPool.execute(task);
            //根据班级id获取一个班级的imei
            List<String> imeiList = classService.getImeiListByClassId(classesId);
            PushMessDataVO pushDeviceTask = new PushMessDataVO();
            pushDeviceTask.setTitle(data.getTitle());
            pushDeviceTask.setContent(data.getContent());
            pushDeviceTask.setId(data.getId());
            pushDeviceTask.setUserId(userId);
            //给设备推送过去
            ForkJoinPushTask task2 = new ForkJoinPushTask(pushDeviceTask, imeiList, 1);
            ForkJoinPoolUtils.forkJoinPool.execute(task2);
        }
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 获取微信扫码的条件信息
     *
     * @param request
     * @return
     */
    @GetMapping("/getScanCodeCondition")
    public RespEntity getScanCodeCondition(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/getScanCodeCondition : userId = {},url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = WxScanCodeUtils.getScanCodeCondition(url);
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }

    /**
     * 获取微信扫码的条件信息（喜马拉雅）
     *
     * @param request
     * @return
     */
    @GetMapping("/getScanCodeConditionXmly")
    public RespEntity getScanCodeConditionXmly(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/getScanCodeConditionXmly : userId = {} , url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = WxScanCodeUtils.getScanCodeConditionXmly(url);
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }

    /**
     * 获取微信扫码的条件信息创维
     */
    @GetMapping("/getScanCodeConditionCW")
    public RespEntity getScanCodeConditionCW(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/getScanCodeConditionCW : userId = {} , url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = WxScanCodeUtils.getScanCodeConditionCW(url);
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }

    /**
     * 获取微信扫码的条件信息小湃
     *
     * @param url
     * @param request
     * @return
     */
    @GetMapping("/getScanCodeConditionXB")
    public RespEntity getScanCodeConditionXB(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/getScanCodeConditionXB : userId = {} , url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = WxScanCodeUtils.getScanCodeConditionXB(url);
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }

    /**
     * 获取微信扫码的条件信息（瑞翼）
     *
     * @param request
     * @return
     */
    @GetMapping("/getScanCodeConditionRy")
    public RespEntity getScanCodeConditionRy(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/getScanCodeConditionRy : userId = {} , url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = WxScanCodeUtils.getScanCodeConditionRy(url);
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }

    /**
     * 获取客户微信扫码条件
     */
    @GetMapping("/getCustomerScanCodeCondition")
    public RespEntity getCustomerScanCodeCondition(@RequestParam("url") String url, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        WxUser wxUser = wxService.getWxUserById(userId);
        if (wxUser == null || wxUser.getWxCustomer() == null) {
            return new RespEntity(RespCode.NO_RIGHT_OPERATION);
        }
        WxCustomer wxCustomer = wxCustomerService.getWxCustomerById(wxUser.getWxCustomer());
        logger.info("/getScanCodeConditionRy : userId = {} , url = {}", userId.toString(), url);
        Map<String, Object> scanCodeCondition = wxUtilsService.getScanCodeCondition(url, wxCustomer.getAppId(), wxCustomer.getAppSecret());
        return new RespEntity(RespCode.SUCCESS, scanCodeCondition);
    }


    /**
     * 获取设置页各模式的设置状态
     */
    @GetMapping("/getModeStatus/{stuId}")
    public RespEntity getModeStatus(@PathVariable("stuId") Integer stuId) {
        logger.info("/getModeStatus : stuId = {} ", stuId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //获取各模式的状态
        Map<String, Object> map = deviceInfoService.getModeStatusByDeviceId(deviceInfo.getDeviceId(), deviceInfo.getImei());
        /* map.put("locateMode", deviceInfo.getWorkingPattern() == null ? Constants.DEFAULT_WORK_PATTERN : deviceInfo.getWorkingPattern());*/
        return new RespEntity(RespCode.SUCCESS, map);
    }

    /**
     * 获取定位模式的信息
     */
    @GetMapping("/getLocateModeMess/{stuId}")
    public RespEntity getLocateModeMess(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("/getLocateModeMess : stuId = {} ", stuId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //获取设备的定位模式信息
        Map<String, Object> result = new HashMap<>();
        if (deviceInfo.getWorkingPattern() == null) {
            result.put("realTimeMode", Constants.UP_INTERVAL);
            result.put("powerSaveMode", Constants.POWER_SAVING_MODEL_UP_INTERVAL);
            result.put("type", Constants.DEFAULT_WORK_PATTERN);
        } else if (deviceInfo.getWorkingPattern() == Constants.DEFAULT_WORK_PATTERN) {
            result.put("realTimeMode", deviceInfo.getUpInterval());
            result.put("powerSaveMode", Constants.POWER_SAVING_MODEL_UP_INTERVAL);
            result.put("type", Constants.DEFAULT_WORK_PATTERN);
        } else if (deviceInfo.getWorkingPattern() == Constants.POWER_SAVING_MODEL) {
            result.put("realTimeMode", Constants.UP_INTERVAL);
            result.put("powerSaveMode", deviceInfo.getUpInterval());
            result.put("type", Constants.POWER_SAVING_MODEL);
        }
       /* result.put("mode", deviceInfo.getWorkingPattern() == null ? Constants.DEFAULT_WORK_PATTERN : deviceInfo.getWorkingPattern());
        result.put("interval", deviceInfo.getUpInterval() == null ? Constants.UP_INTERVAL : deviceInfo.getUpInterval());*/
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 设置定位模式
     */
    @PostMapping("/setLocateMode")
    public RespEntity setLocateMode(@RequestBody WxLocateModeVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setLocateMode : data = {} ", data.toString());
        boolean b = veryAuthentication(data.getStuId(), userId);
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                //获取流水号
                String command = getCurTime();
                boolean b1 = commandSendUtils.setDeviceMode(deviceInfo.getImei(), command, data.getMode(), data.getInterval(), isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取睡眠模式信息
     */
    @GetMapping("/getSleepModeMess/{stuId}")
    public RespEntity getSleepModeMess(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("/getSleepModeMess : stuId = {} ", stuId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //获取设备获取设备设置信息
        DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
        Integer sleepSwitch = setting.getSleepSwitch();
        String sleepStart = setting.getSleepStart();
        String sleepEnd = setting.getSleepEnd();
        Map<String, Object> result = new HashMap<>();
        result.put("sleepSwitch", sleepSwitch == null ? Constants.SLEEP_SWITCH_CLOSE : sleepSwitch);
        result.put("sleepStart", StringUtils.isBlank(sleepStart) ? Constants.SLEEP_DEFAULT_START : sleepStart);
        result.put("sleepEnd", StringUtils.isBlank(sleepEnd) ? Constants.SLEEP_DEFAULT_END : sleepEnd);
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 设置睡眠模式
     */
    @PostMapping("/setSleepMode")
    public RespEntity setSleepMode(@RequestBody WxSleepModeVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setSleepMode : data = {} ", data.toString());
        boolean b = veryAuthentication(data.getStuId(), userId);
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
                if (setting == null) {
                    return new RespEntity(RespCode.DEVICE_SETTING_NOT_EXIST);
                }
                //如果是关闭，则获取数据库中的开始结束时间
                if (data.getSwitchFlag() == Constants.SLEEP_SWITCH_CLOSE) {
                    data.setStartTime(StringUtils.isBlank(setting.getSleepStart()) ? Constants.SLEEP_DEFAULT_START : setting.getSleepStart());
                    data.setEndTime(StringUtils.isBlank(setting.getSleepEnd()) ? Constants.SLEEP_DEFAULT_END : setting.getSleepEnd());
                }
                //获取流水号
                String command = getCurTime();
                boolean b1 = commandSendUtils.setSleepTimeAutoChangeMode(deviceInfo.getImei(), command, data.getStartTime(), data.getEndTime(), data.getSwitchFlag(), isOnline, Constants.WX_COMMAND_USER_ID, false);
                if (b1) {
                    //加个判断，如果现在正处于睡眠模式中，则提示模式结束后执行指令
                    if (setting.getSleepSwitch() != null && setting.getSleepSwitch() == Constants.SLEEP_SWITCH_OPEN) {
                        boolean b2 = judgeSleepTimeReply(setting.getSleepStart(), setting.getSleepEnd());
                        if (b2) {
                            return new RespEntity(RespCode.WAIT_END_SET_SLEEP_TIME);
                        }
                    }
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 远程重启
     */
    @GetMapping("/restartDevice/{stuId}")
    public RespEntity restartDevice(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/restartDevice : stuId = {} ", stuId.toString());
        boolean b = veryAuthentication(stuId, userId);
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                if (isOnline) {
                    //获取流水号
                    String command = getCurTime();
                    boolean b1 = commandSendUtils.restartDevice(deviceInfo.getImei(), command, Constants.WX_COMMAND_USER_ID);
                    if (b1) {
                        return new RespEntity(RespCode.SUCCESS);
                    }
                    return new RespEntity(RespCode.FAILED);
                }
                return new RespEntity(RespCode.DEVICE_NOT_ONLINE);
            }
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 查看设备的静默状态
     */
    @GetMapping("/getSilentShutDownStatus/{stuId}")
    public RespEntity getSilentShutDownStatus(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("/getSilentShutDownStatus : stuId = {} ", stuId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        //获取设备获取设备设置信息
        DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
        Map<String, Object> map = new HashMap<>();
        map.put("silentStatus", setting.getSilentShutdown() == null ? Constants.SILENT_SHUTDOWN_CLOSE : setting.getSilentShutdown());
        return new RespEntity(RespCode.SUCCESS, map);
    }

    /**
     * 设置静默关机
     */
    @PostMapping("/setSilentShutdown")
    public RespEntity setSilentShutdown(@RequestBody SilentShutdownVo data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setSilentShutdown : data = {} ", data.toString());
        boolean b = veryAuthentication(data.getStuId(), userId);
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                //获取流水号
                String command = getCurTime();
                //进行指令下发
                boolean b1 = commandSendUtils.setShutDownSilent(data.getFlagSwitch(), deviceInfo.getImei(), command, Constants.WX_COMMAND_USER_ID, isOnline, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 查询学生的闹钟信息
     */
    @GetMapping("/getAlarmMess/{stuId}")
    public RespEntity getAlarmMess(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("/getAlarmMess : stuId = {} ", stuId.toString());
        Map<String, Object> result = new HashMap<>();
        //首先判断设备是否是有屏幕
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        /*if (deviceInfo.getIfScreen() == null || deviceInfo.getIfScreen() != 1) {
            List<Alarm> list2=new ArrayList<>();
            result.put("if_screen", false);
            result.put("data", list2);
            return new RespEntity(RespCode.SUCCESS, result);
        } else {
            result.put("if_screen", true);
        }*/
        result.put("if_screen", true);
        //有屏幕则查找闹钟信息
        List<Alarm> alarmList = deviceAlarmService.getAlarmListByDeviceId(deviceInfo.getDeviceId());
        //如果是一次性且开启的闹钟，还需要判断是否已经响过了，如果已经响过了则关闭（只是数据库关闭）
        alarmList.stream().forEach(e -> {
            String repeatTime = e.getRepeatTime();
            if ("0000000".equals(repeatTime) && e.getFlag() == 1) {
                Long createTime = e.getCreateTime();
                String time = e.getTime();
                boolean b = judgeIfAlarm(createTime, time);
                if (b) {
                    //已经响过了，则关闭
                    e.setFlag(0);
                    //修改数据库数据
                    deviceAlarmService.closeAlarmById(e.getId(), 0);
                }
            }
        });
        result.put("data", alarmList);
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 开启关闭闹钟
     */
    @GetMapping("/openOrCloseAlarm/{stuId}/{id}/{flag}")
    public RespEntity openOrCloseAlarm(@PathVariable("stuId") Integer stuId, @PathVariable("id") Integer id
            , @PathVariable("flag") Integer flag, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/openOrCloseAlarm : stuId = {} ,id={},flag={}", stuId.toString(), id.toString(), flag.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        boolean b = veryAuthentication(stuId, userId);
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            int realFlag = 0;
            realFlag = flag == 0 ? 1 : 0;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(realFlag);
            deviceAlarm.setName(alarm.getName());
            deviceAlarm.setRepeatTime(alarm.getRepeatTime());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(alarm.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改数据库信息
                alarm.setFlag(realFlag);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCommandNumber(commandNumber);
                if (realFlag == 1 && "0000000".equals(alarm.getRepeatTime())) {
                    alarm.setCreateTime(System.currentTimeMillis());
                }
                int i = deviceAlarmService.modifyAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addAlarm")
    public RespEntity addAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/addAlarm :userId={},data={}", userId.toString(), data.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(data.getStuId(), userId);
        //获取一个可用序列号
        Integer sequence = getAlarmSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.ALARM_HAD_FULL);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            Integer flag = 1;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(flag);
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(sequence);
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //添加一个闹钟
                Alarm alarm = new Alarm();
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_ADD);
                alarm.setFlag(flag);
                alarm.setRepeatTime(data.getRepeat());
                alarm.setDeviceId(deviceInfo.getDeviceId());
                alarm.setName(data.getName());
                alarm.setTime(data.getTime());
                alarm.setSequence(sequence);
                int i = deviceAlarmService.addAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 修改闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifyAlarm")
    public RespEntity modifyAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/modifyAlarm :userId={},data={}", userId.toString(), data.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(data.getStuId(), userId);
        //获取闹钟信息
        Alarm alarm = deviceAlarmService.queryAlarmById(data.getId());
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(alarm.getFlag());
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改一个闹钟
                alarm.setTime(data.getTime());
                alarm.setName(data.getName());
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setRepeatTime(data.getRepeat());
                int i = deviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除一个闹钟
     *
     * @param stuId
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/deleteAlarm/{stuId}/{id}")
    public RespEntity deleteAlarm(@PathVariable("stuId") Integer stuId, @PathVariable("id") Integer id, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /* Integer userId = 3;*/
        logger.info("/deleteAlarm :stuId={},id={}", stuId.toString(), id.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(stuId, userId);
        //获取闹钟信息
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            JSONObject data = new JSONObject();
            data.put("imei", deviceInfo.getImei());
            data.put("commandNumber", commandNumber);
            data.put("sequence", alarm.getSequence());
            boolean b1 = commandSendUtils.deleteAlarm(data, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改闹钟的状态为待删除
                alarm.setStatus(Constants.DEVICE_ALARM_DELETE);
                alarm.setCommandNumber(commandNumber);
                int i = deviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 根据id获取一个闹钟的信息
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getAlarmById/{id}")
    public RespEntity getAlarmById(@PathVariable("id") Integer id, HttpServletRequest request) {
        logger.info("/getAlarmById :id={}", id.toString());
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        return new RespEntity(RespCode.SUCCESS, alarm);
    }


    /**
     * 判断一次性闹钟是否已经响过了
     *
     * @param createTime
     * @param time
     * @return
     */
    public static boolean judgeIfAlarm(Long createTime, String time) {
        //根据创建时间和设置时间，算出第一次响铃时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(createTime);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        String minuteStr = minute < 10 ? "0".concat(String.valueOf(minute)) : String.valueOf(minute);
        String oldTime = String.valueOf(hour).concat(":").concat(minuteStr);
        String[] split = time.split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
        calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
        Long firstAlarm = 0l;
        if (time.compareTo(oldTime) >= 0) {
            //说明第一次铃响跟创建闹钟是在同一天
            firstAlarm = calendar.getTimeInMillis();
        } else {
            //说明第一次响铃是创建闹钟的后一天
            createTime = createTime + 24 * 60 * 60 * 1000;
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTimeInMillis(createTime);
            calendar2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
            calendar2.set(Calendar.MINUTE, Integer.valueOf(split[1]));
            firstAlarm = calendar2.getTimeInMillis();
        }
        return System.currentTimeMillis() > firstAlarm ? true : false;
    }

    /**
     * 获取某天的班级考勤信息
     *
     * @param data
     * @return
     */
    @PostMapping("/getAttendanceMess")
    public RespEntity getAttendanceMess(@RequestBody WxAttendanceVO data) {
        logger.info("/getAttendanceMess :data={}", data.toString());
        //将传入时间转成礼拜几
        int week = translateToWeekDay(data.getTime());
        //判断查询改天的考勤类型是否设备开启
        int i = attendanceRulesService.judgeIfSetRule(week, data.getClassId(), data.getType());
        if (i > 0) {
            //查询该天考勤信息
            //查询班级人数
            int studentNumber = studentService.getStudentNumberByClassId(data.getClassId());
            //获取班级考勤记录
            List<Map<String, Object>> recordList = attendanceRulesService.getStudentAttendanceRecord(data.getClassId(), data.getTime());
            //统计打卡信息
            Map<String, Integer> result = countMess(recordList, data.getType(), studentNumber);
            return new RespEntity(RespCode.SUCCESS, result);
        }
        return new RespEntity(RespCode.SUCCESS, null);
    }

    public Map<String, Integer> countMess(List<Map<String, Object>> list, Integer type, Integer studentNumber) {
        AtomicReference<Integer> normal = new AtomicReference<>(0);
        AtomicReference<Integer> lateOrEarly = new AtomicReference<>(0);
        AtomicReference<Integer> noRecord = new AtomicReference<>(0);
        list.stream().forEach(e -> {
            Integer status = 0;
            switch (type) {
                case 1:
                    status = (Integer) e.get("sign_morning");
                    break;
                case 2:
                    status = (Integer) e.get("leave_morning");
                    break;
                case 3:
                    status = (Integer) e.get("sign_afternoon");
                    break;
                case 4:
                    status = (Integer) e.get("leave_afternoon");
                    break;
                default:
                    break;
            }
            switch (status) {
                case 0:
                    normal.getAndSet(normal.get() + 1);
                    break;
                case 1:
                    noRecord.getAndSet(noRecord.get() + 1);
                    break;
                case 2:
                case 3:
                    lateOrEarly.getAndSet(lateOrEarly.get() + 1);
                    break;
                default:
                    break;
            }
        });
        int noRecord2 = studentNumber - normal.get() - lateOrEarly.get() - noRecord.get();
        Map<String, Integer> result = new HashMap<>();
        result.put("studentNumber", studentNumber);
        result.put("normal", normal.get());
        result.put("lateOrEarly", lateOrEarly.get());
        result.put("noRecord", noRecord.get() + noRecord2);
        return result;
    }

    public int translateToWeekDay(Long time) {
        int[] arr = {7, 1, 2, 3, 4, 5, 6};
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        int week = arr[calendar.get(Calendar.DAY_OF_WEEK) - 1];
        return week;
    }

    /**
     * 获取某天的班级考勤记录
     *
     * @param data
     * @return
     */
    @PostMapping("/getAttendanceRecord")
    public RespEntity getAttendanceRecord(@RequestBody WxAttendanceVO data) {
        logger.info("/getAttendanceRecord :data={}", data.toString());
        //将传入时间转成礼拜几
        int week = translateToWeekDay(data.getTime());
        //判断查询改天的考勤类型是否设备开启
        int i = attendanceRulesService.judgeIfSetRule(week, data.getClassId(), data.getType());
        if (i > 0) {
            //根据条件查询考勤记录
            List<Map<String, Object>> recordList = attendanceRulesService.getWxAttendanceRecordList(data.getClassId(), data.getTime(), data.getType(), data.getStatus());
/*            if (data.getStatus() == 1 || data.getStatus() == 5) {
                //如果是未打卡的，还需要加上没有打卡记录存在的
                //查询没有打卡记录的学生id
                List<Map<String, Object>> unRecordList = attendanceRulesService.getWxUnRecordList(data.getTime(), data.getClassId(), data.getType());
                unRecordList.stream().forEach(e -> {
                    e.put("time", " ");
                    e.put("status", 1);
                });
                List<Map<String, Object>> addList = new ArrayList<>();
                if (unRecordList.size() > 0) {
                    for (int j = 0; j < unRecordList.size(); j++) {
                        boolean flag = true;
                        for (int k = 0; k < recordList.size(); k++) {
                            Integer a = (Integer) recordList.get(k).get("student_id");
                            Integer b = (Integer) unRecordList.get(j).get("student_id");
                            if (a.equals(b)) {
                                flag = false;
                                break;
                            }
                        }
                        if (flag) {
                            addList.add(unRecordList.get(j));
                        }
                    }
                    logger.info("recordList:".concat(recordList.toString()));
                    logger.info("unrecordList".concat(unRecordList.toString()));
                    logger.info("addList:".concat(addList.toString()));
                    recordList.addAll(addList);
                }
            }*/
            return new RespEntity(RespCode.SUCCESS, recordList);
        }
        return new RespEntity(RespCode.SUCCESS, null);
    }

    @GetMapping("/testPush")
    public RespEntity testTemplatePush() {
        TemplateMessageSendResult entryFenceTemplate = PushModel.createEntryFenceTemplate("12345", "name", "fence");
        entryFenceTemplate.setTouser("obdQT6NCqwc___Jh9sn1vIGy4P4I");
        WxUtils.pushMsg(entryFenceTemplate);
        return null;
    }

    /**
     * 获取用户id
     *
     * @param request
     * @return
     */
    public Integer getUserId(HttpServletRequest request) {
        //获取用户id
        String token = request.getHeader(Constants.WX_HEADER_TOKEN_KEY);
        if (token.equals("aaab")) {
            return 3;
        }
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return 0;
        }
        Integer userId = Integer.parseInt(redisUserId);
        return userId;
    }

    /**
     * 获取一个课堂模式可用的序列号
     *
     * @param deviceId
     * @return
     */
    public Integer getClassSequence(Integer deviceId) {
        //获取该设备已经存在的课堂模式
        List<DeviceClassPattern> list = deviceClassPatternService.getDeviceClassesPatternByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceClassPattern classPattern : list) {
            seqList.add(classPattern.getSequence());
        }
        for (int i = 1; i <= 10; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个闹钟的可用的序列号
     *
     * @param deviceId
     * @return
     */
    public Integer getAlarmSequence(Integer deviceId) {
        //获取该设备已经存在的课堂模式
        List<Alarm> list = deviceAlarmService.getAlarmListByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (Alarm alarm : list) {
            seqList.add(alarm.getSequence());
        }
        for (int i = 1; i <= 10; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个可用的亲情号码的序列号
     */
    public Integer getSequence(Integer stuId) {
        //获取该设备已经存在的亲情号序号
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(stuId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceWhiteList deviceWhiteList : list) {
            seqList.add(deviceWhiteList.getSequence());
        }
        for (int i = 4; i <= 6; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个可用的SOS列表的序列号
     */
    public Integer getSosSequence(Integer deviceId) {
        //获取该设备已经存在的SOS告警记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceSOSList deviceSOSList : sosList) {
            seqList.add(deviceSOSList.getSequence());
        }
        for (int i = 1; i <= 3; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个可用的通讯录的序列号
     */
    public Integer getSequenceInLink(Integer stuId) {
        //获取该设备已经存在的亲情号序号
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByStuId(stuId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceWhiteList deviceWhiteList : list) {
            seqList.add(deviceWhiteList.getSequence());
        }
        for (int i = 7; i <= 23; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }

    /**
     * 判断设备是否在线
     *
     * @param imei 设备imei号
     * @return 设备是否在线
     */
    public boolean deviceOnline(String imei) {
        boolean isOnline = redisService.hasKey(Constants.DEVICE_ONLINE_PREFIX + imei);
        logger.info("设备:【{}】: {}", imei, isOnline ? "在线" : "离线");
        return isOnline;
    }


    /**
     * 判断操作的家长是否是学生的主监护人
     *
     * @param stuId
     * @param userId
     * @return
     */
    public boolean veryAuthentication(Integer stuId, Integer userId) {
       /* //根据学生id查找学生信息
        Map<String, Object> student = studentService.getStudentByStuId(stuId);
        //根据微信用户id查询用户电话号码
        String number = deviceWhiteListService.getNumberByWXUserId(userId);
        if (number == null || !((String) student.get("parent_phone")).equals(number)) {
            return false;
        }
        return true;*/
        //根据学生id和用户id查询一条绑定记录
        Map<String, Object> map = wxService.getBindingByStuIdAndUserId(stuId, userId);
        Integer isAuthorization = (Integer) map.get("is_authorization");
        if (isAuthorization == null) {
            return false;
        }
        return isAuthorization == 1 ? true : false;
    }


    /**
     * 获取修改下发设置SOS的参数
     */
    public List<DeviceSOSList> getModifySetSOSList(DeviceSOSList list, Integer deviceId) {
       /* //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        List<Integer> sequenceList = sosList.stream()
                .map(DeviceSOSList::getSequence)
                .collect(Collectors.toList());
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while (iterator.hasNext()) {
            //将从数据库中查询出来的对应的要修改的老数据从list中删除
            DeviceSOSList next = iterator.next();
            if (next.getSequence() == list.getSequence()) {
                iterator.remove();
            }
        }*/
        //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while (iterator.hasNext()) {
            //将从数据库中查询出来的对应的要修改的老数据从list中删除
            DeviceSOSList next = iterator.next();
            if (next.getSequence() == list.getSequence()) {
                iterator.remove();
                continue;
            }
            //如果是碰到状态为待删除的，也将它移除
            if (next.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        //修改界限
        List<Integer> sequenceList = sosList.stream()
                .map(DeviceSOSList::getSequence)
                .collect(Collectors.toList());
        for (int i = 1; i <= 3; i++) {
            //如果是修改的那笔数据的sequence，则直接把修改后的新数据加入进去
            if (i == list.getSequence()) {
                sosList.add(list);
                continue;
            }
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        sosList = sosList.stream()
                .sorted(Comparator.comparing(DeviceSOSList::getSequence))
                .collect(Collectors.toList());
        logger.info("---更新SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 获取添加下发指令设置SOS的参数
     */
    public List<DeviceSOSList> getAddSetSOSList(DeviceSOSList list, Integer deviceId) {
        //根据设备id查找SOS号码记录，这里的sos记录会影响到下面的结果，因为如果是有2和3，则顺序就位231了
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        //修改内容
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while (iterator.hasNext()) {
            DeviceSOSList next = iterator.next();
            //如果数据库有待删除的数据，那么下发的时候需要下发空值，所以这里需要删除掉
            if (next.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        //修改界限
        // 获取数据库有的id
        List<Integer> sequenceList = sosList.stream().map(DeviceSOSList::getSequence).collect(Collectors.toList());
        for (Integer i = 1; i <= 3; i++) {
            // 如果有，则不管，否则就加一个空的
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        // 排序
        sosList = sosList.stream().sorted(Comparator.comparing(DeviceSOSList::getSequence)).collect(Collectors.toList());
        logger.info("---新增SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 获取删除下发指令设置SOS的参数
     */
    public List<DeviceSOSList> getDelSetSOSList(DeviceSOSList list, Integer deviceId) {
        //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        // 排除掉需要删除的，删除的用空
        Iterator iterator = sosList.iterator();
        while (iterator.hasNext()) {
            DeviceSOSList sos = (DeviceSOSList) iterator.next();
            if (sos.getSequence().equals(list.getSequence())) {
                iterator.remove();
                continue;
            }
            //如果是碰到状态为待删除的，也将它移除
            if (sos.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        List<Integer> sequenceList = sosList.stream().map(DeviceSOSList::getSequence).collect(Collectors.toList());
        for (int i = 1; i <= 3; i++) {
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        sosList = sosList.stream()
                .sorted(Comparator.comparing(DeviceSOSList::getSequence))
                .collect(Collectors.toList());
        logger.info("---删除SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 筛选轨迹数据，未超过十米就筛掉
     *
     * @param list
     * @return
     */
    public List<Map<String, Object>> dealLocation(List<Map<String, Object>> list) {
        if (list == null || list.size() <= 2) {
            return list;
        }
        List<Map<String, Object>> result = new ArrayList<>();
        Map<String, Object> curr = list.get(0);
        result.add(curr);
        for (int i = 1; i < list.size() - 1; i++) {
            String longitude = (String) curr.get("longitude");
            String latitude = (String) curr.get("latitude");
            double[] doubles = GPSUtils.gps84_To_Gcj02(Double.parseDouble(latitude), Double.parseDouble(longitude));
            String longitude2 = (String) list.get(i).get("longitude");
            String latitude2 = (String) list.get(i).get("latitude");
            double[] doubles2 = GPSUtils.gps84_To_Gcj02(Double.parseDouble(latitude2), Double.parseDouble(longitude2));
            double distance = GPSUtils.getDistance(doubles[1], doubles[0], doubles2[1], doubles2[0]);
            if (distance > 10) {
                result.add(list.get(i));
                curr = list.get(i);
            }
        }
        result.add(list.get(list.size() - 1));
        return result;
    }

    /**
     * 挑选一个合适的学生id
     *
     * @param list
     * @param imei
     * @return
     */
    public Integer selectStudentId(List<Map<String, Object>> list, String imei, String deviceOrgCode) {
/*        if (list.size() == 1) {
            return (Integer) list.get(0).get("student_id");
        }*/
        List<Integer> stuIdList = new ArrayList<>();
        list.stream().forEach(e -> {
            stuIdList.add((Integer) e.get("student_id"));
        });
        List<DeviceInfo> deviceList = deviceInfoService.getDeviceInfoListByStuIdList(stuIdList);
        //默认取第一个
        Integer stuId = (Integer) list.get(0).get("student_id");
        if (deviceList != null && deviceList.size() != 0) {
            for (DeviceInfo deviceInfo : deviceList) {
                if (deviceInfo.getImei().equals(imei)) {
                    stuId = deviceInfo.getStudentId();
                    return stuId;
                }
                //筛选掉已经绑定设备的
                if (stuIdList.contains(deviceInfo.getStudentId())) {
                    stuIdList.remove(deviceInfo.getStudentId());
                }
            }
        }
        //进一步筛选学校的组织和设备的组织是否匹配
        //根据学生id获取学校组织code
        if (deviceOrgCode != null) {
            if (stuIdList.size() > 0) {
                List<Map<String, Object>> schoolOrgCodeList = studentService.getSchoolOrgCodeListByStuIdList(stuIdList);
                for (Map<String, Object> map : schoolOrgCodeList) {
                    String schoolCode = (String) map.get("org_code");
                    if (!schoolCode.contains(deviceOrgCode)) {
                        Integer stuId2 = (Integer) map.get("student_id");
                        stuIdList.remove(stuId2);
                    }
                }
            }
        }
        //到此处若还有值，则取第一个
        if (stuIdList.size() > 0) {
            return stuIdList.get(0);
        }
        return 0;
    }


    public boolean judgeSleepTimeReply(String start, String end) {
        //获取当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String now = sdf.format(new Date(System.currentTimeMillis()));
        if (end.compareTo(start) > 0) {
            //结束时间比开始时间大
            if (now.compareTo(start) > 0 && end.compareTo(now) > 0) {
                return true;
            }
            return false;
        } else {
            //结束时间比开始时间小(跨天)
            if (now.compareTo(start) > 0 && now.compareTo(end) > 0) {
                return true;
            } else if (now.compareTo(start) < 0 && now.compareTo(end) < 0) {
                return true;
            }
            return false;
        }
    }

    /**
     * 消息提醒位置固定
     *
     * @param result
     * @return
     */
    public List<Map<String, Object>> changePlace(List<Optional<Map<String, Object>>> result) {
        List<Map<String, Object>> newList = new ArrayList<>(10);
        for (int i = 0; i < 6; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("content", "暂无记录");
            map.put("warning_time", System.currentTimeMillis());
            map.put("isNew", false);
            if (i == 0) {
                map.put("warnName", "校园通知");
                map.put("warning_type", "0");
                newList.add(0, map);
            } else if (i == 1) {
                map.put("warnName", "低电量提醒");
                map.put("warning_type", Constants.LOW_BATTERY_WARNING_TYPE);
                newList.add(1, map);
            } else if (i == 2) {
                map.put("warnName", "SOS提醒");
                map.put("warning_type", Constants.SOS_WARNING_TYPE);
                newList.add(2, map);
            } else if (i == 3) {
                map.put("warnName", "围栏提醒");
                map.put("warning_type", 5);
                newList.add(3, map);
            } else if (i == 4) {
                map.put("warnName", "开机提醒");
                map.put("warning_type", Constants.POWER_ON_WARNING_TYPE);
                newList.add(4, map);
            } else if (i == 5) {
                map.put("warnName", "关机提醒");
                map.put("warning_type", Constants.SHUT_DOWN_WARNING_TYPE);
                newList.add(5, map);
            }
        }
        result.stream().forEach(e -> {
            Map<String, Object> map = e.get();
            Integer type = (Integer) map.get("warning_type");
            if (type.equals(Constants.LOW_BATTERY_WARNING_TYPE)) {
                newList.add(1, map);
            } else if (type.equals(Constants.SOS_WARNING_TYPE)) {
                newList.add(2, map);
            } else if (type.equals(5)) {
                newList.add(3, map);
            } else if (type.equals(Constants.POWER_ON_WARNING_TYPE)) {
                newList.add(4, map);
            } else if (type.equals(Constants.SHUT_DOWN_WARNING_TYPE)) {
                newList.add(5, map);
            }
        });
        return newList;
    }

    public static void main(String[] args) {
     /*   List<Map<String, Object>> newList = new ArrayList<>(10);
        Map<String, Object> map = new HashMap<>();
        newList.add(0, map);
        newList.add(1, map);
        newList.add(2, map);*/
       /* String time = "15:00";
        Long createTime = 1637049600000l;
        boolean b = judgeIfAlarm(createTime, time);*/
        String s = UnicodeUtil.decodeUnicode("\\u0031\\u0035\\u0031\\u0033\\u0038\\u0036\\u0038\\u0033\\u0035\\u0034\\u0037");
        System.out.println(s);
    }

    /**
     * 点击菜单进行消息回复
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value = "/getMenuReply", produces = MediaType.APPLICATION_XML_VALUE)
    public String receiveWX(HttpServletRequest request, HttpServletResponse response) {
        logger.info("/getMenuReply");
        try {
            Marshaller marshaller;
            Unmarshaller unmarshal;
            //你要解析成哪个bean对象，newInstance的参数就是哪个对象
            JAXBContext jaxbContext = JAXBContext.newInstance(WXMessageBean.class);
            unmarshal = jaxbContext.createUnmarshaller();
            //xml解码成bean对象
            WXMessageBean wxMessgeBean = (WXMessageBean) unmarshal.unmarshal(request.getInputStream());
            //准备返回文字信息
            WXMessageBean bean = new WXMessageBean();
            bean.setFromUserName(wxMessgeBean.getToUserName());
            bean.setToUserName(wxMessgeBean.getFromUserName());
            bean.setCreateTime(new Date().getTime());
            //通过对比菜单的key设置对应的返回值
            if (wxMessgeBean.getEventKey().equals("11")) {
                bean.setMsgType("aa");
                bean.setContent("你好，欢迎浏览我的公众号");
            } else {
                bean.setMsgType("text");
                bean.setContent("我不认识你");
            }
            //把bean对象组装成xml格式，并返回
            marshaller = jaxbContext.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(bean, writer);
            return writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
